본문 바로가기

Front-end/React

Zustand란? React 전역 상태 관리 쉽게 이해하기

 

 

React로 개발하다 보면 여러 컴포넌트에서 같은 데이터를 사용해야 할 때가 있다.

예를 들어 로그인한 사용자 정보, 다크모드 여부, 장바구니 목록, 검색 조건 같은 데이터는 한 컴포넌트에서만 사용하는 것이 아니라 여러 화면에서 함께 사용할 수 있다.

이런 데이터를 관리할 때 사용하는 것이 전역 상태 관리이고, Zustand는 React에서 전역 상태를 쉽게 관리할 수 있게 도와주는 라이브러리이다.

 

 

1. Zustand란?

Zustand는 React에서 사용하는 상태 관리 라이브러리이다.

Redux처럼 전역 상태를 관리할 수 있지만, 코드가 훨씬 짧고 사용 방법이 간단하다.

npm install zustand

2. 왜 Zustand를 사용할까?

React에서는 기본적으로 useState를 사용해서 상태를 관리한다.

const [count, setCount] = useState(0);

하지만 이 상태를 여러 컴포넌트에서 같이 사용하려면 props로 계속 전달해야 한다.

App
 ├── Header
 ├── Main
 │    └── Counter
 └── Footer

예를 들어 count 값을 HeaderCounter에서 같이 사용하고 싶다면, 부모 컴포넌트를 통해 props를 계속 내려줘야 한다.

이런 방식은 컴포넌트가 많아질수록 복잡해진다.


3. Zustand를 사용하면?

Zustand는 상태를 저장하는 store를 만든다.

        Zustand Store
        count: 0
        increase()
        decrease()

       /        \
  Header       Counter

이제 필요한 컴포넌트에서 바로 store 값을 가져와 사용할 수 있다.

props로 계속 전달하지 않아도 된다.


4. 기본 예제: 카운터 만들기

먼저 store 파일을 만든다.

store/useCounterStore.js

import { create } from "zustand";

const useCounterStore = create((set) => ({
  count: 0,

  increase: () =>
    set((state) => ({
      count: state.count + 1,
    })),

  decrease: () =>
    set((state) => ({
      count: state.count - 1,
    })),

  reset: () =>
    set({
      count: 0,
    }),
}));

export default useCounterStore;

5. store 코드 설명

import { create } from "zustand";

create는 Zustand store를 만들 때 사용하는 함수이다.

const useCounterStore = create((set) => ({
  count: 0,
}));

여기서 count는 전역으로 관리할 상태이다.

increase: () =>
  set((state) => ({
    count: state.count + 1,
  })),

increase는 count 값을 1 증가시키는 함수이다.

set을 사용하면 store 안의 값을 변경할 수 있다.


6. 컴포넌트에서 사용하기

Counter.jsx

import useCounterStore from "./store/useCounterStore";

function Counter() {
  const count = useCounterStore((state) => state.count);
  const increase = useCounterStore((state) => state.increase);
  const decrease = useCounterStore((state) => state.decrease);
  const reset = useCounterStore((state) => state.reset);

  return (
    <div>
      <h2>Zustand Counter</h2>

      <p>현재 숫자: {count}</p>

      <button onClick={increase}>증가</button>
      <button onClick={decrease}>감소</button>
      <button onClick={reset}>초기화</button>
    </div>
  );
}

export default Counter;

실행 화면 예시

Zustand Counter

현재 숫자: 0

[ 증가 ] [ 감소 ] [ 초기화 ]

증가 버튼을 누르면:

현재 숫자: 1

감소 버튼을 누르면:

현재 숫자: 0

초기화 버튼을 누르면 다시 0이 된다.


7. 여러 컴포넌트에서 같은 상태 사용하기

Zustand의 장점은 여러 컴포넌트에서 같은 상태를 쉽게 공유할 수 있다는 점이다.

Header.jsx

import useCounterStore from "./store/useCounterStore";

function Header() {
  const count = useCounterStore((state) => state.count);

  return (
    <header>
      <h3>Header</h3>
      <p>현재 count 값: {count}</p>
    </header>
  );
}

export default Header;

Counter.jsx

import useCounterStore from "./store/useCounterStore";

function Counter() {
  const count = useCounterStore((state) => state.count);
  const increase = useCounterStore((state) => state.increase);

  return (
    <div>
      <h3>Counter</h3>
      <p>현재 count 값: {count}</p>
      <button onClick={increase}>증가</button>
    </div>
  );
}

export default Counter;

App.jsx

import Header from "./Header";
import Counter from "./Counter";

function App() {
  return (
    <div>
      <Header />
      <Counter />
    </div>
  );
}

export default App;

실행 흐름

Counter에서 증가 버튼 클릭
        ↓
Zustand Store의 count 값 변경
        ↓
Header와 Counter가 같은 count 값을 바라봄
        ↓
두 컴포넌트 화면이 같이 변경됨

즉, Counter에서 값을 변경했는데 Header에서도 변경된 값을 바로 확인할 수 있다.


8. 로그인 상태 관리 예시

실제 프로젝트에서는 카운터보다 로그인 사용자 정보 같은 데이터를 전역 상태로 많이 관리한다.

store/useUserStore.js

import { create } from "zustand";

const useUserStore = create((set) => ({
  user: null,
  isLogin: false,

  login: (userData) =>
    set({
      user: userData,
      isLogin: true,
    }),

  logout: () =>
    set({
      user: null,
      isLogin: false,
    }),
}));

export default useUserStore;

Login.jsx

import useUserStore from "./store/useUserStore";

function Login() {
  const login = useUserStore((state) => state.login);

  const handleLogin = () => {
    login({
      id: 1,
      name: "홍길동",
      email: "test@test.com",
    });
  };

  return (
    <div>
      <h2>Login Page</h2>
      <button onClick={handleLogin}>로그인</button>
    </div>
  );
}

export default Login;

Profile.jsx

import useUserStore from "./store/useUserStore";

function Profile() {
  const user = useUserStore((state) => state.user);
  const isLogin = useUserStore((state) => state.isLogin);
  const logout = useUserStore((state) => state.logout);

  return (
    <div>
      <h2>Profile</h2>

      {isLogin ? (
        <>
          <p>이름: {user.name}</p>
          <p>이메일: {user.email}</p>
          <button onClick={logout}>로그아웃</button>
        </>
      ) : (
        <p>로그인이 필요합니다.</p>
      )}
    </div>
  );
}

export default Profile;

로그인 예제 실행 흐름

1. Login 컴포넌트에서 로그인 버튼 클릭
2. login 함수 실행
3. Zustand Store에 user 정보 저장
4. isLogin 값 true로 변경
5. Profile 컴포넌트에서 로그인 정보 출력

실행 화면 예시:

Profile

이름: 홍길동
이메일: test@test.com

[ 로그아웃 ]

로그아웃 버튼을 누르면:

Profile

로그인이 필요합니다.

9. Redux와 Zustand 차이

Redux와 Zustand는 둘 다 전역 상태 관리를 위해 사용한다.

하지만 코드 작성 방식이 다르다.

Redux
Action → Reducer → Store → Component

Zustand
Store → Component

Redux는 구조가 명확하고 큰 프로젝트에서 많이 사용된다.
하지만 처음 배우는 입장에서는 action, reducer, dispatch 같은 개념이 어렵게 느껴질 수 있다.

Zustand는 store를 만들고 바로 가져다 쓰는 방식이라 훨씬 직관적이다.


10. Zustand 장점

Zustand의 장점은 다음과 같다.

1. 코드가 짧다.
2. 사용법이 쉽다.
3. props drilling을 줄일 수 있다.
4. Redux보다 설정이 간단하다.
5. 작은 프로젝트부터 큰 프로젝트까지 사용할 수 있다.

특히 처음 상태 관리를 배우는 사람에게는 Redux보다 Zustand가 더 쉽게 느껴질 수 있다.


11. Zustand를 언제 사용하면 좋을까?

다음과 같은 상태를 관리할 때 Zustand를 사용하면 좋다.

로그인 사용자 정보
다크모드 설정
장바구니 목록
검색 조건
모달 열림/닫힘 상태
페이지 공통 필터

예를 들어 쇼핑몰 프로젝트라면 장바구니 데이터를 Zustand로 관리할 수 있다.

상품 목록 페이지
      ↓
장바구니 담기 클릭
      ↓
Zustand Store에 상품 추가
      ↓
Header 장바구니 개수 자동 변경

최종 정리

Zustand는 React에서 전역 상태를 쉽게 관리할 수 있게 도와주는 라이브러리이다.

useState는 한 컴포넌트 안에서 상태를 관리할 때 좋고,
Zustand는 여러 컴포넌트에서 같은 상태를 공유해야 할 때 좋다.

useState
→ 한 컴포넌트 안에서 상태 관리

Zustand
→ 여러 컴포넌트에서 공유하는 전역 상태 관리

Zustand의 핵심은 간단하다.

1. create로 store 만들기
2. store 안에 state와 함수 작성하기
3. 컴포넌트에서 필요한 값만 가져다 쓰기

처음 React 상태 관리를 공부한다면 Zustand는 Redux보다 훨씬 쉽게 시작할 수 있는 좋은 선택이다.