React
[React] Zustand란?
yo09
2025. 1. 10. 10:05
Zustand란?
Zustand는 독일어로 "상태"라는 뜻으로, 리액트 상태 관리를 간단하고 효율적으로 할 수 있게 도와주는 라이브러리이다. 상태(state)를 더 직관적이고 깔끔하게 관리할 수 있도록 설계되었다.
왜 Zustand를 사용할까?
리액트에서 기본적으로 제공하는 useState와 useReducer를 사용해도 상태 관리는 충분히 가능하다. 하지만 다음과 같은 경우, Zustand가 더 좋은 대안이 될 수 있다.
1. 상태가 복잡해질 때
- 프로젝트가 커질수록 상태가 여기저기 분산되어 관리하기 어려워진다.
- 여러 컴포넌트에서 동일한 상태를 공유하거나, 상호작용해야 할 때는 props를 계속 전달해야 해서 코드가 복잡해진다.
- Zustand는 중앙 저장소(store)를 만들어 상태를 한 곳에서 관리하고, 필요한 컴포넌트가 그 상태를 가져다 쓰게 해줍니다.
2. props로 상태를 계속 전달해야 할 때
- 리액트에서는 부모에서 자식 컴포넌트로 상태를 내려주기 위해 props를 사용한다.
- 하지만, 컴포넌트가 많아지면 props를 계속 전달하는 작업이 반복되어 코드가 복잡해지고 가독성이 떨어집니다. 이를 "props drilling"이라고 한다.
- Zustand는 상태를 중앙에서 관리하기 때문에 props drilling 문제를 깔끔하게 해결한다.
3. Redux처럼 복잡한 설정이 싫을 때
- Redux도 상태 관리 라이브러리지만, 설정 과정이 복잡하고 코드가 길어질 수 있다.
- Zustand는 설치와 사용이 간단하며, 몇 줄의 코드로 상태를 관리할 수 있다.
기존 리액트 상태 관리와 Zustand 비교
리액트 (useState) | Zustand | |
설정 | 별도 설치 없이 바로 사용 가능 | 라이브러리 설치 필요 |
상태 공유 | props를 통해 부모에서 자식으로 전달 | 여러 컴포넌트에서 바로 상태 접근 가능 |
코드 복잡도 | 컴포넌트 간 상태 전달이 많아 복잡할 수 있음 | 상태 접근이 직관적이고 코드가 간단 |
복잡한 상태 관리 | 상태가 많아지면 비효율적일 수 있음 | 복잡한 상태도 중앙에서 쉽게 관리 가능 |
학습 곡선 | 쉬움 | 쉬움 (Redux보다 훨씬 간단) |
Zustand를 언제 사용할까?
- 여러 컴포넌트에서 동일한 상태를 사용해야 할 때
예) 로그인 상태, 쇼핑몰 장바구니 데이터, 공통 설정 정보 등 - props로 상태를 여러 단계 전달하는 게 번거로울 때
예) 부모-자식-손자 컴포넌트로 계속 props를 전달해야 하는 경우 - Redux는 너무 복잡하다고 느낄 때
예) 작은 프로젝트나 간단한 상태 관리가 필요한 경우 - 리액트 상태 관리를 더 간단히 하고 싶을 때
Zustand 사용법
1. 설치
Zustand는 NPM 명령어로 간단히 설치할 수 있다.
npm install zustand
2. Store 만들기
Zustand에서 상태는 store(저장소)에 정의한다.
예를 들어, 메모를 작성하는 기능을 만든다고 가정해보겠다.
// stores/memos.js
import create from 'zustand';
const useMemosStore = create((set) => ({
memo: '', // 하나의 메모 상태
setMemo: (text) => set({ memo: text }), // 메모 상태 업데이트 함수
memos: [], // 모든 메모를 저장할 배열 상태
setMemos: (newMemo) =>
set((prev) => ({
memos: [...prev.memos, newMemo], // 기존 메모에 새로운 메모 추가
})),
}));
export default useMemosStore;
3. Store 사용하기
만들어진 상태를 컴포넌트에서 가져와 사용한다.
메모 작성 폼 컴포넌트
// components/Form.js
import useMemosStore from '../stores/memos';
const Form = () => {
const { memo, setMemo, setMemos } = useMemosStore();
const handleWriteMemo = (e) => {
setMemo(e.target.value); // 입력값을 memo에 저장
};
const handleAddMemo = (e) => {
e.preventDefault();
setMemos(memo); // 메모를 추가
setMemo(''); // 입력창 초기화
};
return (
<form onSubmit={handleAddMemo}>
<input type="text" value={memo} onChange={handleWriteMemo} />
<button type="submit">메모 추가</button>
</form>
);
};
메모 리스트 컴포넌트
// components/Memos.js
import useMemosStore from '../stores/memos';
const Memos = () => {
const { memos } = useMemosStore();
return (
<ul>
{memos.map((memo, index) => (
<li key={index}>{memo}</li>
))}
</ul>
);
};
4. App.js에서 상태 삭제
Zustand로 상태를 관리하기 때문에, App.js에서는 더 이상 상태를 정의하거나 전달할 필요가 없다.
// App.js
import Form from './components/Form';
import Memos from './components/Memos';
function App() {
return (
<div>
<h1>Zustand 메모 앱</h1>
<Form />
<Memos />
</div>
);
}
export default App;