Javascript

[React]Redux와 Context API

LSH2118 2024. 10. 16. 10:02

우리의 웹페이지가 복잡해지면

데이터를 보내는 데에 불필요한 과정이 생길 수도 있다

 

A - B - C - D처럼 데이터가 A에서 D로 가는 과정이 길어지고

B와 C는 오로지 값을 전달하는 역할만 수행한다

 

이러한 현상을 Prop Drilling이라 부릅니다

 

Prop Drilling을 방지하고자 Context API Redux를 사용한다


Context API

위에서 설명한 것처럼 Prop Drilling을 방지하기 위해 사용한다

 

React에 기본적으로 포함된 기능이라, 별도의 설치가 필요 없다.

그냥 React에서 제공하는 createContextuseContext를 사용하면 된다.

 

1. Context 생성

import { createContext } from 'react';

const UserContext = createContext();

export default UserContext;

먼저 따로 파일을 만들어서 creacteContext();를 사용해서 Context를 생성한다

 

이렇게 생성하면 다른 컴포넌트에서도 import로 끌어와서 사용할 수 있다

 

2. Provider로 데이터 제공

import UserContext from "./context/context";

function App() {
  const username = "Mr. Lee"

  return (
    <UserContext.Provider value={username}>
      <Parants />
    </UserContext.Provider>
  );
}

export default App;

 

가장 최상위 컴포넌트를 <{Context 이름}.Provider>로 감싸줍니다

 

.Provider로 감쌈으로써 하위의 컴포넌트에서 username을 받아서 사용할 수 있습니다

 

보동 App.js가 최상위 컴포넌트라 App안에 감쌌고 username을 선언한 뒤

value={userName}를 작성하였습니다

 

3.Context 데이터 사용하기

값을 전달받았으면 사용해야겠죠?

import{ React, useContext }from "react";
import UserContext from "../context/context";

function Parants(){
    const userName = useContext(UserContext);
    
    return(
        <div>
            <h1>hello {userName}!</h1>
        </div>
    )
}

export default Parants;

1 Context를 사용하는 컴포넌트는  useContext훅을 사용해 값을 가져올 수 있습니다

 

결과를 보면

이렇게 정상적으로 출력되는 것을 볼 수 있다

 

이렇게 장점도 명확하지만 Context API는 단점도 명확하다

 

Context API의 단점

Context API의 단점이라고 하면 크게 2가지를 꼽을 수 있습니다

 

1. 성능 문제

Context의 값이 변경되면 아래의 해당값을 사용하는 모든 컴포넌트들이 전부 리렌더링이 된다

 

이는 성능이 저하되는 현상을 초래할 수 있다

2. 비교적 제한된 기능

복잡한 상태 관리(예: 비동기 작업 처리, 미들웨어 등)를 위한 추가적인 구조가 필요할 수 있습니다.

 

만약 비동기 작업 중 하나인 서버에서 데이터를 가져오는 경우를 가정하면 Context API로는 

완전히 동작하기에 부족함이 있을 수 있습니다

 

이외에도 복잡한 상태 구조 관리의 한계, 구독 범위의 제한 등 다양한 단점이 존재합니다

 

Redux

Redux는 Javascript의 상태를 관리하기 위한 라이브러리입니다

애플리케이션의 상태를 중앙에서 관리하고, 이 상태를 예측 가능한 방식으로 업데이트하도록 도와줍니다.

 

Redux Toolkit

Redux의 공식 권장 도구로, Redux 사용을 더 쉽고 효율적으로 만들어주는 라이브러리입니다.

Redux의 복잡한 설정과 불필요한 보일러플레이트 코드를 줄여주고, 상태 관리의 복잡성을 해결하는 데 중점을 둔 도구입니다.

 

다운로드

npm install @reduxjs/toolkit react-redux

 

리덕스는 스토어(store), 액션(action), 리듀서(reducer), 그리고 디스패치(dispatch)가 필요합니다.

 

설명의 편의를 위해서 버튼을 누르면 count가 1씩 증가하거나 감소하는 웹페이지를 만들어 보겠습니다

Store

import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './counterReducer';

const store = configureStore({
  reducer: counterReducer,
});

export default store;

스토어(store)는 상태를 중앙에서 관리하는 역할을 합니다

 

configureStore을 사용해 reducer을 선언합니다

 

Action & Reducer

// counterSlice.js
import { createSlice } from '@reduxjs/toolkit';

// createSlice로 슬라이스 생성
const counterSlice = createSlice({
  name: 'counter', // 슬라이스 이름
  initialState: { count: 0 }, // 초기 상태

  // 리듀서 부분: 상태를 어떻게 업데이트할지 정의
  reducers: {
    increment: (state) => {
      state.count += 1;  // 카운트 증가
    },
    decrement: (state) => {
      state.count -= 1;  // 카운트 감소
    },
  },
});

// 액션 부분: 각 리듀서에 대한 액션 생성
export const { increment, decrement } = counterSlice.actions;

// 리듀서 부분: store에 등록될 리듀서 추출
export default counterSlice.reducer;

원래는 action과 reducer을 따로 만들어 줘야 하지만 앞서 설치했던 tooltik덕분에 createSlice를 사용하면 함께 생성할 수 있습니다

 

Reducer은 상태를 어떻게 업데이트할지 정의하는 역할을 수행하고

Action은 정의한 Reducer의 대한 트리거 역할을 합니다

 

먼저 creacteSlice로 counterSlice를 생성해 줍니다.

그 후에 슬라이스 이름과 초기상태를 정해 줍니다

 

그 후 리듀서 부분을 정의합니다

 

액션은 각각의 리듀서에 대한 액션을 생성합니다

 

그리고 store에 등록할 리듀서를. reducer로 추출합니다

 

Dispatch

디스패치(dispatch)는 액션을 스토어로 내보내는 함수입니다

쉽게 말해 액션을 시작하게 하는 트리거역할입니다

// App.js
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement } from './counterSlice';

function App() {
  const count = useSelector((state) => state.count); // 상태 가져오기
  const dispatch = useDispatch(); // 디스패치 함수 가져오기

  return (
    <div>
      <h1>카운터: {count}</h1>
      <button onClick={() => dispatch(increment())}>증가</button>
      <button onClick={() => dispatch(decrement())}>감소</button>
    </div>
  );
}

export default App;

먼저 useSelector상태를 가져옵니다

 

그 후 useDispatch();를 사용해 디스페치 함수를 가져옵니다

 

이제 우리는 클릭할 때 increment와 decrement가 작동되게 하면 끝납니다

작동시키는 방법은 useDispatch로 감싸주면 안에 있는 것 "디스패치 한다"라는 뜻입니다

 

그래서 결과물을 보면

이렇게 정상 작동 합니다

 

Redux vs Context API

그래서 둘 중 뭐가 더 좋냐?

Context API

장점

  1. 간단한 사용법: React의 내장 기능으로, 추가 라이브러리 설치가 필요 없습니다.
  2. 적은 코드 양: 작은 애플리케이션이나 특정 상태 관리에는 코드가 적게 들고 간단합니다.
  3. React와의 통합: React의 컴포넌트 트리와 자연스럽게 통합되어 사용됩니다.
  4. 프로그래밍 유연성: 더 자유로운 구조와 컴포넌트 간의 직접적인 데이터 전달이 가능합니다.

단점

  1. 성능 문제: 콘텍스트의 값이 변경되면 해당 값을 사용하는 모든 컴포넌트가 리렌더링 됩니다. 큰 애플리케이션에서는 성능 저하가 발생할 수 있습니다.
  2. 비교적 제한된 기능: 복잡한 상태 관리(예: 비동기 작업 처리, 미들웨어 등)를 위한 추가적인 구조가 필요할 수 있습니다.

Redux

장점

  1. 예측 가능한 상태 관리: 상태가 한 곳에서 관리되므로, 애플리케이션의 상태 흐름을 쉽게 추적할 수 있습니다.
  2. 미들웨어 지원: Redux Saga, Redux Thunk 등과 같은 미들웨어를 사용하여 비동기 작업을 쉽게 처리할 수 있습니다.
  3. 플러그인 생태계: 다양한 플러그인과 도구(예: Redux DevTools)가 있어 상태 관리를 더 쉽게 할 수 있습니다.
  4. 성능 최적화: 리렌더링 최적화가 가능하여, 상태 변경 시 필요한 컴포넌트만 업데이트할 수 있습니다.

단점

  1. 복잡성: 설정과 코드가 더 복잡해질 수 있으며, 많은 보일러플레이트 코드가 필요합니다.
  2. 학습 곡선: 특히 Redux의 개념(액션, 리듀서 등)을 이해하기까지 시간이 걸릴 수 있습니다.

 

 

결론

Context API는 소규모 애플리케이션이나 단순한 상태 관리에 적합합니다. React의 기본 기능으로 쉽게 시작할 수 있고

Redux는 중대형 애플리케이션에서 더 효과적이며, 복잡한 상태 관리와 비동기 처리를 잘 처리합니다. 하지만 학습 비용과 코드 복잡성이 더 높습니다.

 

이러한 장단점을 잘 숙지하고 프로젝트의 특성에 맞게 활용한다면, 더 효율적이고 확장성 있는 웹 애플리케이션을 제작할 수 있을 것입니다.

 

 

'Javascript' 카테고리의 다른 글

Monorepo  (1) 2025.02.02
[Javascript]다국어 지원하기  (1) 2024.11.27
[Javascript] CORS가 뭘까?  (0) 2024.09.09
[Javascript]JS로 API연결 실제로 해봤다  (1) 2024.08.03
[Javascript] API통신이 뭘까?  (0) 2024.08.03