React 상태관리 완벽 가이드
· 약 3분
React 애플리케이션이 커지면서 상태 관리는 필수적인 고려사항이 됩니다. 이 글에서는 다양한 상태 관리 방법을 비교해봅니다.
상태 관리가 필요한 이유
React의 단방향 데이터 흐름은 예측 가능한 코드를 만들지만, 컴포넌트가 깊어지면 Props Drilling 문제가 발생합니다.
Props Drilling이란?
부모에서 자식으로 props를 여러 단계에 걸쳐 전달해야 하는 상황을 말합니다. 중간 컴포넌트들이 실제로 사용하지 않는 props를 전달만 하는 것은 비효율적입니다.
상태 관리 옵션 비교
1. React Context
React 내장 기능으로 별도 라이브러리 없이 사용 가능합니다.
import { createContext, useContext, useState } from 'react';
interface ThemeContextType {
theme: 'light' | 'dark';
toggleTheme: () => void;
}
const ThemeContext = createContext<ThemeContextType | null>(null);
export function ThemeProvider({ children }: { children: React.ReactNode }) {
const [theme, setTheme] = useState<'light' | 'dark'>('light');
const toggleTheme = () => {
setTheme((prev) => (prev === 'light' ? 'dark' : 'light'));
};
return <ThemeContext.Provider value={{ theme, toggleTheme }}>{children}</ThemeContext.Provider>;
}
export const useTheme = () => {
const context = useContext(ThemeContext);
if (!context) throw new Error('useTheme must be used within ThemeProvider');
return context;
};
2. Zustand
가볍고 간단한 상태 관리 라이브러리입니다.
import { create } from 'zustand';
interface CounterState {
count: number;
increment: () => void;
decrement: () => void;
}
const useCounter = create<CounterState>((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
decrement: () => set((state) => ({ count: state.count - 1 })),
}));
3. Jotai
원자적(atomic) 상태 관리를 제공합니다.
import { atom, useAtom } from 'jotai';
const countAtom = atom(0);
const doubledCountAtom = atom((get) => get(countAtom) * 2);
function Counter() {
const [count, setCount] = useAtom(countAtom);
const [doubled] = useAtom(doubledCountAtom);
return (
<div>
<p>Count: {count}</p>
<p>Doubled: {doubled}</p>
<button onClick={() => setCount((c) => c + 1)}>+</button>
</div>
);
}
성능 비교
각 라이브러리의 번들 크기를 비교하면:
| 라이브러리 | 크기 (gzip) | 특징 |
|---|---|---|
| Context | 0 KB | 내장 |
| Zustand | ~1.5 KB | 간결함 |
| Jotai | ~3 KB | 원자적 |
| Redux TK | ~11 KB |
