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 API | Redux | Zustand | Recoil |
|---|---|---|---|---|
| 번들 크기 | 0KB | 3KB | 2KB | 4KB |
| 학습 곡선 | 낮음 | 높음 | 낮음 | 중간 |
| 개발자 도구 | 없음 | 좋음 | 기본 | 기본 |
| 미들웨어 | 없음 | 많음 | 가능 | 없음 |
| 코드 량 | 적음 | 많음 | 적음 | 중간 |
선택 기준
- 작은 프로젝트: Context API
- 대규모 복잡한 앱: Redux
- 가볍고 간단함: Zustand
- 원자적 상태: Recoil
- 반응형 프로그래밍: MobX
베스트 프랙티스
// 상태 정규화
// 나쁜 예
{
users: [
{ id: 1, name: 'A', posts: [...] }
]
}
// 좋은 예
{
users: {
1: { id: 1, name: 'A' }
},
posts: {
1: { id: 1, userId: 1, content: '...' }
}
}
올바른 상태 관리 라이브러리를 선택하는 것이 애플리케이션 개발의 핵심입니다.