최근 프로젝트에서 헤더에 있는 플러스 버튼으로 그리드 레이아웃(예: 9열, 3열, 1열)을 전환하는 기능을 구현하려고 했다.
처음에는 Home 컴포넌트 내부 상태만 바꾸면 되겠다고 생각해서 Home 컴포넌트에서 gridState라는 useState를 만들어 관리했는데, 막상 헤더에서 plus 버튼을 누르면 이 상태가 업데이트되지 않아 그리드 전환이 되지 않았다.
처음엔 Prop Drilling으로 해결할까 했지만 구조가 복잡해질 것 같았다. 차라리 글로벌 상태 관리 라이브러리를 써보자 싶어서 Zustand를 도입했다. 써보니 Redux처럼 많은 보일러플레이트가 필요 없고, 훨씬 간단했다.
대략적인 구현 과정은 이랬다:
- useGridStore.ts 파일을 만들고, gridState(예: "grid9", "grid3", "grid1")를 저장하는 store를 정의했다.
- Header와 Home 컴포넌트 둘 다에서 useGridStore를 임포트한 뒤, 그 안에 있는 gridState를 구독하도록 만들었다.
- Header의 플러스 버튼을 누르면 store에 있는 setGridState를 호출하여 gridState를 "grid9"에서 "grid3", 혹은 "grid3"에서 "grid1"로 변경해 줬다.
- Home 컴포넌트에서도 useGridStore를 통해 gridState를 구독하고, gridState 값에 따라 실제 그리드 레이아웃(9열, 3열, 1열)을 렌더링하도록 했다.
이렇게 하니, 헤더에서 플러스 버튼을 눌렀을 때 Home 컴포넌트가 곧바로 상태 변화를 감지하고, 원하는 대로 그리드를 부드럽게 전환할 수 있었다.
간단한 예시 코드
useGridStore.ts
import create from 'zustand';
type GridState = 'grid9' | 'grid3' | 'grid1';
interface GridStore {
gridState: GridState;
setGridState: (state: GridState) => void;
}
const useGridStore = create<GridStore>((set) => ({
gridState: 'grid9',
setGridState: (state) => set({ gridState: state }),
}));
export default useGridStore;
Header.tsx
import useGridStore from '../store/useGridStore';
const Header: React.FC = () => {
const { gridState, setGridState } = useGridStore();
const handlePlusClick = () => {
if (gridState === 'grid9') setGridState('grid3');
else if (gridState === 'grid3') setGridState('grid1');
};
// ...
};
회고
이전까지는 이런 간단한 전역 상태도 어차피 지금은 prop만 넘기면 되지않나 싶어 넘어가곤 했다. 그런데 한두 번이 아니라 서로 다른 컴포넌트에서 동일 상태를 써야 할 때는 글로벌 상태가 훨씬 편하다는 걸 느꼈다. Redux가 너무 과하다고 생각될 때, Zustand를 써보면 딱 적절하다는 걸 배웠다. 다음에도 비슷한 상황이 오면 쉽게 적용할 수 있을 것 같다.
'Zustand' 카테고리의 다른 글
Zustand로 React 상태 업데이트 지연 문제 해결하기 (0) | 2025.02.10 |
---|