어제 Context API를 공부하고 정리하면서, 전역 상태 관리를 할 수 있는 다른 방법도 있다는 것을 알게 되었다. 그래서 오늘은 가볍고 간편하며 요즘 자주 사용된다고 하는 Zustand에 대해 공부하고 정리해보았다.
Zustand(주스탄드)는 독일어로 "상태"를 뜻하며, React 프로젝트에서 사용할 수 있는 가볍고 빠른 상태 관리 라이브러리이다.

하지만 다른 상태 관리 라이브러리인 Redux가 여전히 압도적으로 많이 사용되고 있다. 다만 Redux는 문법이 복잡하고 학습 난이도가 높아 초보자들에게 진입장벽이 될 수 있다. 이런 이유로, 가볍고 사용이 간편한 Zustand가 요즘 많은 주목을 받고 있다고 한다.
Store(스토어)는 Zustand에서 사용하는 상태 관리 방법으로, 애플리케이션의 여러 데이터를 중앙에서 관리하는 개념이다. 이를 통해 컴포넌트 간 데이터를 쉽게 공유하고, 데이터의 변경을 감지하여 자동으로 리렌더링할 수 있다. 이 방식은 특히 애플리케이션에서 복잡한 상태를 관리할 때 유용하다.

이전 글에서도 설명한 prop drilling을 방지하는 데에도 store가 사용될 수 있다. Context API도 데이터를 전달하는 동안 중간 단계 컴포넌트를 거칠 필요가 없지만, Zustand의 store는 상태를 전역적으로 관리하여 중간 컴포넌트를 거치지 않고도 쉽게 데이터에 접근할 수 있도록 도와준다. 이를 통해 컴포넌트 간 결합도를 낮추고, 유지보수와 확장이 용이해진다.
글만 보면 Context API의 Provider와 Zustand의 Store가 비슷해 보일 수 있지만, 실제로는 큰 차이가 있다.
Context API는 Provider로 감싸진 컴포넌트 계층 내에서만 데이터를 공유할 수 있다. 즉, 특정 Context를 사용하려면 반드시 Provider의 자식 컴포넌트로 포함되어야 하며, 컴포넌트 트리 구조에 의존적이다.
하지만 Zustand의 Store를 생성하면 특정 컴포넌트 계층에 국한되지 않고, 어디에서든 상태를 단독적으로 사용할 수 있다. 컴포넌트 트리와 독립적으로 동작하며, 전역적으로 상태를 관리할 수 있다는 점에서 유연성이 뛰어나다.
먼저 순서대로 정리해보면
Zustand의 create 함수를 이용해 Store를 생성한다.
create 함수의 콜백은 set과 get을 매개변수로 가지며, 이를 통해 상태를 변경하거나 조회할 수 있다.
콜백 함수가 반환하는 객체에서 속성은 현재 상태를 나타내며, 이를 State(상태)라고 부른다. 그리고 메소드는 상태를 변경하는 동작을 정의하며, 이를 Action(액션)이라고 부른다.
create 호출은 Store를 반환하며, 이를 React 컴포넌트에서 사용하기 위해 Hook(훅) 형태로 만들어 사용한다. 예를 들어, useCountStore와 같은 이름으로 정의하여 컴포넌트에서 쉽게 상태를 관리할 수 있도록 한다.
이제 코드로 살펴보자.
import { create } from "zustand"
export const use이름Store = create((set, get) => {
return {
상태: 초깃값,
액션: 함수
}
})
이것이 Store를 생성하는 가장 기본적인 형태이다.
사용 예시는 아래와 같이 활용할 수 있다.
import { create } from "zustand"
export const useCountStore = create((set, get) => ({
count: 0,
increment: () => {
const { count } = get();
set({ count: count + 1 });
},
decrement: () => {
const { count } = get();
set({ count: count - 1 });
}
}));
아래처럼 get 함수를 사용하지 않고, set 함수의 콜백을 사용하면 더 간결하게 상태를 변경할 수 있다.
import { create } from "zustand";
export const useCountStore = create((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
decrement: () => set((state) => ({ count: state.count - 1 })),
}));
이제 생성한 Store를 사용해보자
import { useCountStore } from "./store/count";
function App() {
const { count, increment, decrement } = useCountStore();
return (
<>
<h1>{count}</h1>
<button onClick={increment}>증가</button>
<button onClick={decrement}>감소</button>
</>
);
}
export default App;
오늘은 Context API에 이어, 요즘 자주 사용된다고 하는 Zustand에 대해 공부하고 정리해봤다. Zustand는 Context API와 달리 컴포넌트 트리 구조에 의존하지 않고 사용할 수 있다는 점이 정말 마음에 들었다. 기본적인 사용법도 매우 간단해서 앞으로 유용하게 활용할 수 있을 것 같다.