React 상태 관리: Redux에서 Zustand까지

개발팀
3분 읽기
React상태관리상태

React 상태 관리: Redux에서 Zustand까지

React 애플리케이션의 상태 관리는 복잡할 수 있습니다. 다양한 옵션을 살펴봅시다.

Context API (빌트인)

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

// Provider
function App() {
  const [theme, setTheme] = useState('light');
  return (
    <ThemeContext.Provider value={{ theme, setTheme }}>
      <MyComponent />
    </ThemeContext.Provider>
  );
}

// 사용
function MyComponent() {
  const { theme, setTheme } = useContext(ThemeContext);
  return <div className={theme}>...</div>;
}

Redux

// Slice 정의 (Redux Toolkit)
import { createSlice } from '@reduxjs/toolkit';

const counterSlice = createSlice({
  name: 'counter',
  initialState: { value: 0 },
  reducers: {
    increment: (state) => { state.value += 1; },
    decrement: (state) => { state.value -= 1; }
  }
});

// 스토어 설정
import { configureStore } from '@reduxjs/toolkit';

const store = configureStore({
  reducer: {
    counter: counterSlice.reducer
  }
});

// 컴포넌트에서 사용
function Counter() {
  const count = useSelector(state => state.counter.value);
  const dispatch = useDispatch();

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => dispatch(counterSlice.actions.increment())}>
        +
      </button>
    </div>
  );
}

Zustand

import create from 'zustand';

// 스토어 정의
const useStore = create((set) => ({
  count: 0,
  increment: () => set(state => ({ count: state.count + 1 })),
  decrement: () => set(state => ({ count: state.count - 1 })),
  reset: () => set({ count: 0 })
}));

// 컴포넌트에서 사용
function Counter() {
  const { count, increment, decrement } = useStore();

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

Recoil

import { atom, selector, useRecoilState } from 'recoil';

// Atom 정의
const countAtom = atom({
  key: 'count',
  default: 0
});

// Selector 정의
const countSelector = selector({
  key: 'countX2',
  get: ({ get }) => {
    return get(countAtom) * 2;
  }
});

// 컴포넌트에서 사용
function Counter() {
  const [count, setCount] = useRecoilState(countAtom);
  const countX2 = useRecoilValue(countSelector);

  return (
    <div>
      <p>Count: {count}</p>
      <p>Count x2: {countX2}</p>
      <button onClick={() => setCount(count + 1)}>+</button>
    </div>
  );
}

MobX

import { makeAutoObservable } from 'mobx';
import { observer } from 'mobx-react-lite';

// 스토어 정의
class CounterStore {
  count = 0;

  constructor() {
    makeAutoObservable(this);
  }

  increment() {
    this.count++;
  }

  decrement() {
    this.count--;
  }
}

// 컴포넌트 (observer로 감싸기)
const Counter = observer(({ store }) => (
  <div>
    <p>Count: {store.count}</p>
    <button onClick={() => store.increment()}>+</button>
  </div>
));

상태 관리 라이브러리 비교

특징Context APIReduxZustandRecoil
번들 크기0KB3KB2KB4KB
학습 곡선낮음높음낮음중간
개발자 도구없음좋음기본기본
미들웨어없음많음가능없음
코드 량적음많음적음중간

선택 기준

  1. 작은 프로젝트: Context API
  2. 대규모 복잡한 앱: Redux
  3. 가볍고 간단함: Zustand
  4. 원자적 상태: Recoil
  5. 반응형 프로그래밍: MobX

베스트 프랙티스

// 상태 정규화
// 나쁜 예
{
  users: [
    { id: 1, name: 'A', posts: [...] }
  ]
}

// 좋은 예
{
  users: {
    1: { id: 1, name: 'A' }
  },
  posts: {
    1: { id: 1, userId: 1, content: '...' }
  }
}

올바른 상태 관리 라이브러리를 선택하는 것이 애플리케이션 개발의 핵심입니다.

React 상태 관리: Redux에서 Zustand까지 | 블로그