본문 바로가기

Web/Frontend 기본 CS 정리

Context API와 Redux를 비교해주세요.

728x90

답변

Context API는 React에 내장된 상태 관리 도구로, 간단한 전역 상태 관리에 적합하며 추가 라이브러리 설치가 필요하지 않습니다. 하지만 성능 최적화가 어렵고 대규모 애플리케이션에는 부적합할 수 있습니다. 반면 Redux는 복잡한 상태 관리와 비동기 처리가 필요한 대규모 애플리케이션에 적합합니다. 단일 스토어에서 상태를 예측 가능하게 관리하며, Redux Thunk나 Saga를 사용해 비동기 로직을 처리할 수 있습니다. 하지만 보일러플레이트 코드가 많고 소규모 프로젝트에서는 복잡도가 증가할 수 있습니다.

 

Context API 특징

  • Context API는 React에 내장되어있어 추가 라이브러리 설치가 필요하지 않음
  • 단순한 전역 상태 관리 기법으로 간단하게 사용하기 좋음
  • 컨텍스트가 변경되면 해당 컨텍스트를 사용하는 모든 컴포넌트가 리렌더링되므로, 큰 애플리케이션에서는 성능 문제가 발생할 수 있음

Context API 사용 코드

Context 생성

import React, { createContext, useContext, useState } from 'react';

// Context 생성
const MyContext = createContext();

// Context 제공 컴포넌트
export function MyProvider({ children }) {
  const [state, setState] = useState("초기 값");

  return (
    <MyContext.Provider value={{ state, setState }}>
      {children}
    </MyContext.Provider>
  );
}

Context 사용

import React, { useContext } from 'react';
import { MyContext } from './MyProvider';

function MyComponent() {
  const { state, setState } = useContext(MyContext);

  return (
    <div>
      <p>{state}</p>
      <button onClick={() => setState("새 값")}>변경</button>
    </div>
  );
}

Redux 특징

  • Redux는 중앙 집중식 상태 관리로 애플리케이션의 전체 상태를 단일 스토어에서 관리하기 때문에 상태 변경의 흐름을 파악하기 좋음
  • Redux는 상태 변경이 액션에 의해 트리거되며 리듀서가 상태를 처리하여 새로운 상태를 반환함.
  • 상태는 불변성을 유지하며 변경
  • Redux는 비동기 로직을 처리하기 위해 Redux Thunk나 Redux Saga 같은 미들웨어를 사용할 수 있습니다.
  • 설정 및 사용에 있어 리듀서, 액션, 스토어 설정 등으로 인해 코드가 복잡해질 수 있습니다.

리듀서와 스토어 생성

import { createStore } from 'redux';

const initialState = { count: 0 };

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return { count: state.count + 1 };
    case 'DECREMENT':
      return { count: state.count - 1 };
    default:
      return state;
  }
};

const store = createStore(reducer);

React와 Redux 연결

import React from 'react';
import { Provider, useDispatch, useSelector } from 'react-redux';
import { createStore } from 'redux';

const reducer = (state = { count: 0 }, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return { count: state.count + 1 };
    case 'DECREMENT':
      return { count: state.count - 1 };
    default:
      return state;
  }
};

const store = createStore(reducer);

function Counter() {
  const count = useSelector((state) => state.count);
  const dispatch = useDispatch();

  return (
    <div>
      <p>{count}</p>
      <button onClick={() => dispatch({ type: 'INCREMENT' })}>+</button>
      <button onClick={() => dispatch({ type: 'DECREMENT' })}>-</button>
    </div>
  );
}

function App() {
  return (
    <Provider store={store}>
      <Counter />
    </Provider>
  );
}

export default App;