프론트엔드 상태 관리는 컴포넌트 간 공유 상태를 일관되게 유지하는 패턴과 라이브러리를 말한다. Redux는 예측 가능한 단방향 데이터 흐름으로, Zustand는 최소한의 보일러플레이트로 상태를 관리한다.
tsx
// store/counterSlice.ts
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
const counterSlice = createSlice({
name: 'counter',
initialState: { value: 0 },
reducers: {
increment: state => { state.value += 1; },
decrement: state => { state.value -= 1; },
incrementBy: (state, action: PayloadAction<number>) => {
state.value += action.payload;
},
},
});
export const { increment, decrement, incrementBy } = counterSlice.actions;
export default counterSlice.reducer;
// store/index.ts
import { configureStore } from '@reduxjs/toolkit';
const store = configureStore({ reducer: { counter: counterSlice.reducer } });
// 컴포넌트에서 사용
import { useDispatch, useSelector } from 'react-redux';
function Counter() {
const count = useSelector((state: RootState) => state.counter.value);
const dispatch = useDispatch();
return <button onClick={() => dispatch(increment())}>{count}</button>;
}
Zustand
tsx
import { create } from 'zustand';
interface BearState {
bears: number;
increase: () => void;
reset: () => void;
}
const useBearStore = create<BearState>(set => ({
bears: 0,
increase: () => set(state => ({ bears: state.bears + 1 })),
reset: () => set({ bears: 0 }),
}));
// 어느 컴포넌트에서든 바로 사용
function BearCounter() {
const bears = useBearStore(state => state.bears);
const increase = useBearStore(state => state.increase);
return <button onClick={increase}>{bears} bears</button>;
}
라이브러리 비교
| Redux | Zustand | Jotai | Recoil |
|---|
| 패러다임 | Flux | 단순 스토어 | 원자(Atom) | 원자(Atom) |
| 보일러플레이트 | 많음 | 적음 | 매우 적음 | 적음 |
| DevTools | 강력 | 기본 | 있음 | 있음 |
| 번들 크기 | 큼 | 작음 | 매우 작음 | 큼 |
| 비동기 | Thunk/Saga | 내장 | 내장 | Selector |
관련 개념