메가바이트스쿨 프론트엔드 4기 15주차 - React(3) redux/useContext

임성열·2023년 4월 5일

메가바이트스쿨

목록 보기
12/13
post-thumbnail

React에서 전역 상태를 관리하는 방법인 useContext와 Redux를 정리한 글입니다.

useContext

useContext는 컴포넌트 트리의 모든 레벨을 통해 props를 전달하지 않고도 여러 컴포넌트 간에 상태를 공유할 수 있게 해주는 React의 내장 후크이다.

useContext는 컨텍스트 객체를 생성하고 이를 공유 상태에 액세스해야 하는 자식 구성 요소에 제공하는 방식으로 작동한다.

예시 코드

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

//CountContext 객체 생성
const CountContext = createContext();

function Counter() {
  const [count, setCount] = useState(0);

  return (
    //Provider 하위 요소들이 useContext를 통해 접근 가능
    <CountContext.Provider value={count}>
      <h1>Count: {count}</h1>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <ChildComponent />
    </CountContext.Provider>
  );
}

function ChildComponent() {
  const count = useContext(CountContext);

  return <h2>Count: {count}</h2>;
}

useContext는 component drilling 없이 구성 요소 간에 상태를 공유하기 위해 쓰인다. 그러나 여러 구성 요소에서 상태를 관리하는 것이 더 어려울 수 있으며 깊이 중첩된 구성 요소 트리로 인해 성능 문제가 발생할 수 있다.

useContext vs useState

useState는 Component의 로컬 상태 관리를 하기 위한 훅이고, useContext는 Component의 하위 요소들에게 전역적으로 상태를 접근하기 위한 훅이다.
예로 들어, 부모 요소인 <Parent />와 자식 요소인 <A />, 그리고 <A />의 자식 요소인 <B />가 있다고 했을 때, <Parent />에서 useState로 생성한 상태는 props drilling을 통하지 않으면 <B />에서는 접근이 불가능하도록 구조되어 있다. 그러나, useContext를 사용하면 접근이 가능하다.

Redux

Redux는 중앙화된 방식으로 애플리케이션의 상태를 관리하는 방법을 제공하는 상태 관리 라이브러리다.

  • 단방향 데이터 흐름으로 구성된 Flux 아키텍처를 따른다.
  • Redux에서 애플리케이션의 state는 변경 불가능한 객체인 단일 저장소(store)에 저장한다.
  • store는 action을 dispatch 해야만 수정 가능하다.
  • store는 reducer를 사용하여 작업에 대한 응답으로 상태가 어떻게 변경되어야 하는지 결정한다.

Redux의 장점 중 하나는 복잡한 구조를 전역 상태로 쉽게 관리할 수 있다는 것이다.
코드를 더 체계적으로 관리하고 유지할 수 있도록 각각 store, reducer, action, dispatch로 나누어 상태를 관리한다.

Redux 설치

$ npm install redux react-redux
또는
$ yarn add redux react-redux

예시 코드

reducer

// counter.js
const initialState = 0

//action.type은 actions.js 에서 불러온 action객체의 프로퍼티
const counterReducer = (state = initialState, action) => {
  switch (action.type) {
    case "INCREMENT":
      return state + 1;
    case "DECREMENT":
      return state - 1;
    default:
      return state;
  }
};

export default counterReducer;

store

// store.js
import { createStore } from "redux";
import counterReducer from "./counter";

//store를 생성하여 counter reducer를 인수로 할당
const store = createStore(counterReducer);

export default store;

actions

// actions.js
export const INCREMENT = "INCREMENT";
export const DECREMENT = "DECREMENT";

export const increment = () => ({
  type: INCREMENT,
});

export const decrement = () => ({
  type: DECREMENT,
});

Counter.jsx

// Counter.jsx
import { useSelector, useDispatch } from "react-redux";
import { increment, decrement } from "./actions";

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

  return (
    <div>
      <h2>Count: {count}</h2>
      <button onClick={() => dispatch(increment())}>+</button>
      <button onClick={() => dispatch(decrement())}>-</button>
    </div>
  );
}

export default Counter;

App.jsx

// App.jsx

import { Provider } from "react-redux";
import store from "./store";

function App() {
  return (
    <Provider store={store}>
      <div className="App">
        <h1>Counter App</h1>
        <Counter />
      </div>
    </Provider>
  );
}

export default App;

Redux vs useContext

useContext는 전체 앱의 한 부분이 전역 객체를 필요로 할 때 사용하고, Redux는 전체 앱이나 전체적인 공통 상태가 복합적으로 다루어져야 할 때 사용한다. 그다지 복잡하지 않고, 규모가 적은 부분의 전역 상태 관리라면 useContext를 사용해 번들 사이즈의 감소등을 노려 오버헤드를 방지하는 것이 좋다.

Redux Toolkit

Redux팀에서 만든 Redux 유틸리티 모음 킷 같은 라이브러리다.
반복적으로 사용되는 필수 코드들을 이쁘게 모아놓고 편하게 쓸 수 있다.

  • 단순한 스토어 설정: Redux Toolkit을 사용하여 저장소를 설정하고 기본적으로 몇 가지 유용한 미들웨어를 활성화하는 configureStore 기능이 포함되어 있다.

  • 간결하고 예측 가능한 코드: Redux Toolkit은 action과 reducer 같은 일반적인 Redux 패턴을 단순화하는 일련의 API 기능을 제공한다. 이러한 기능은 코드를 줄이고 Redux 코드를 더 예측 가능하고 추론하기 쉽게 만드는 데 도움이 된다.

  • 불변성 및 성능 최적화: Redux Toolkit은 내부적으로 Immer 라이브러리를 사용하여 변경 가능한 방식으로 상태를 수정할 수 있는 리듀서 함수 작성할 수 있다. 이렇게 하면 리듀서 작성이 더 쉬워지고 경우에 따라 성능이 향상될 수 있다.

  • 개발 도구에 대한 기본 지원: Redux Toolkit에는 강력한 디버깅 및 시간 이동 기능을 제공하는 브라우저 확장인 Redux DevTools Extension이 있다.

0개의 댓글