본문으로 건너뛰기

"react" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

React 상태관리 완벽 가이드

· 약 3분
dev-burnern
Developer

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>
);
}

성능 비교

각 라이브러리의 번들 크기를 비교하면:

Bundle Impact=Library SizeTotal Bundle×100%\text{Bundle Impact} = \frac{\text{Library Size}}{\text{Total Bundle}} \times 100\%
라이브러리크기 (gzip)특징
Context0 KB내장
Zustand~1.5 KB간결함
Jotai~3 KB원자적
Redux TK~11 KB완전함

선택 가이드

성능 주의

Context API는 값이 변경되면 모든 Consumer가 리렌더링됩니다. 성능이 중요한 경우 상태를 분리하거나 다른 솔루션을 고려하세요.

실제 적용 예시

다음은 Docker Compose로 개발환경 구축하기 환경에서 React 앱을 개발할 때의 상태 관리 패턴입니다.

서버 상태 vs 클라이언트 상태

// 서버 상태: React Query 사용
const { data, isLoading } = useQuery({
queryKey: ['users'],
queryFn: fetchUsers,
});

// 클라이언트 상태: Zustand 사용
const { filter, setFilter } = useFilterStore();

결론

추천 조합
  • 서버 상태: TanStack Query (React Query)
  • 클라이언트 상태: Zustand 또는 Jotai
  • 폼 상태: React Hook Form

프로젝트 규모와 팀의 익숙함에 따라 적절한 도구를 선택하세요.

참고 자료

  • React 공식 문서
  • Zustand GitHub
  • Jotai 문서