모던 전역 상태 관리 아키텍처: Context API의 한계와 Zustand 도입
🚇 Context API: Props Drilling 문제 해결하기
Props Drilling의 고통과 Context API
부모에서 아주 깊은 곳에 있는 자식 컴포넌트로 데이터를 전달하려면, 중간에 있는 컴포넌트들은 데이터를 쓰지도 않으면서 오직 전달만을 위해 Props를 받아 넘겨야 합니다. 이를 Props Drilling(프롭스 내리꽂기)이라고 합니다.
Context API는 이러한 문제를 해결하는 리액트 내장 전역 상태 관리 도구입니다. 최상위에서 Provider로 감싸고 값을 공급하면, 하위의 어떤 컴포넌트든 깊이와 상관없이 useContext 훅을 이용해 해당 값을 바로 꺼내 쓸 수 있습니다.Props Drilling vs Context API
언제 Context API를 써야 할까?
Context API는 만능 전역 상태 관리 도구가 아닙니다. 'Props Drilling을 우회하여 값을 전달하는 통로'에 가깝습니다. 상태가 자주 변경되는 경우 하위 컴포넌트 전체가 리렌더링 될 수 있으므로, 테마(Dark/Light), 로그인 유저 정보, 다국어 설정 등 변경이 잦지 않은 전역 데이터에 사용하는 것이 적합합니다.
import React, { useState } from 'react';
import { ThemeContext } from './ThemeContext';
import MiddleComponent from './MiddleComponent';
// 4. 최상위 부모 컴포넌트
export default function App() {
const [theme, setTheme] = useState('light');
const toggleTheme = () => setTheme(prev => prev === 'light' ? 'dark' : 'light');
return (
// Provider의 value 속성으로 공유할 데이터와 함수를 전달합니다.
<ThemeContext.Provider value={{ theme, toggleTheme }}>
<div style={{ padding: '20px', background: '#f8fafc', borderRadius: '8px' }}>
<h3 style={{ marginTop: 0 }}>Context API 예제</h3>
<MiddleComponent />
</div>
</ThemeContext.Provider>
);
}Redux의 시대는 가고, Zustand의 시대가 왔다
Context API는 전역 상태가 바뀔 때마다 하위 컴포넌트가 전부 리렌더링되는 성능 이슈가 있어, 단순한 테마 변경 정도에만 적합합니다. 그래서 과거에는 무겁고 복잡한 Redux를 사용했습니다.
독일어로 '상태'를 뜻하는 Zustand(쥬스탠드)는 Redux의 단점(방대한 보일러플레이트 코드, 복잡한 설정)을 모두 없앤 초경량 상태 관리 라이브러리입니다. Provider로 앱을 감쌀 필요도 없고, 훅을 생성하여 어디서든 직관적으로 상태와 함수를 꺼내 쓸 수 있습니다.
Zustand의 전역 상태 구조
Zustand 스토어는 리액트 컴포넌트 트리 바깥에 완전히 독립적으로 존재합니다. 따라서
<Provider>로 앱을 감쌀 필요가 없으며, 깊숙한 곳에 있는 컴포넌트라도 훅(Hook)을 통해 스토어에 직접 연결(Subscribe)되어 최상의 렌더링 성능을 보장합니다.
Terminal
위 명령어로 Zustand를 설치한 뒤, 아래와 같이 스토어를 생성하고 컴포넌트에서 활용할 수 있습니다.
import BearCounter from './BearCounter';
import Controls from './Controls';
export default function App() {
// Provider 태그가 아예 필요 없습니다!
return (
<div style={{ padding: '20px', background: '#f8fafc', borderRadius: '8px' }}>
<BearCounter />
<Controls />
</div>
);
}