본문 바로가기
React

[React] 전역 상태 zustand

by wildOjisan 2025. 5. 10.

my_react_app.zip
0.18MB

 

설치 : npm install zustand

 

✅ 목표

  • 전역 상태를 zustand로 만든다.
  • 상태는 모든 페이지에서 공통으로 사용 가능하다.
  • 페이지 새로고침을 해도 상태가 유지된다.
  • 테스트할 수 있는 버튼과 출력 화면도 만든다.

 

상태 저장소 만들기 (src/store/counterStore.ts)

src 폴더 안에 store 폴더를 만들고, 그 안에 counterStore.ts 파일을 만들자.

📄 src/store/counterStore.ts

import { create } from 'zustand'
import { persist } from 'zustand/middleware'

interface CounterState {
  count: number
  increase: () => void
  reset: () => void
}

export const useCounterStore = create<CounterState>()(
  persist(
    (set) => ({
      count: 0,
      increase: () => set((state) => ({ count: state.count + 1 })),
      reset: () => set({ count: 0 }),
    }),
    {
      name: 'counter-storage', // localStorage에 저장될 key 이름
    }
  )
)

🔍 설명

  • create() : zustand 스토어를 만든다.
  • persist() : 새로고침해도 값이 유지되게 한다 (localStorage 사용).
  • increase() : 숫자를 +1 한다.
  • reset() : 숫자를 0으로 초기화한다.

 

테스트용 페이지 만들기 (src/pages/CounterPage.tsx)

📄 src/pages/CounterPage.tsx

import React from "react";
import { useCounterStore } from "../store/counterStore";

const CounterPage: React.FC = () => {
  const count = useCounterStore((state) => state.count);
  const increase = useCounterStore((state) => state.increase);
  const reset = useCounterStore((state) => state.reset);

  return (
    <div style={{ padding: "2rem" }}>
      <h1>🔢 Zustand 전역 상태 테스트</h1>
      <p>현재 숫자: {count}</p>
      <button onClick={increase}>+1 증가</button>
      <button onClick={reset} style={{ marginLeft: "1rem" }}>
        리셋
      </button>
    </div>
  );
};

export default CounterPage;

 

 

라우팅 연결하기 (App.tsx 수정)

App.tsx에 이 페이지를 연결해보자.

📄 src/App.tsx 수정

import React from "react";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import CounterPage from "./pages/CounterPage";

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<CounterPage />} />
      </Routes>
    </BrowserRouter>
  );
}

export default App;

 

 

 

-------------------------------------------------보충----------------------------------------------------

🔢 상태(state)가 이렇게 있다고 해보자:

{
  count: 3
}

버튼을 클릭하면 아래 코드가 실행돼:

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

이걸 천천히 설명하면:

  1. state는 현재 상태값이야. { count: 3 } 이 상태를 받아옴.
  2. state.count는 현재 숫자 3.
  3. state.count + 1 은 4가 됨.
  4. 그래서 새로 저장할 값은 { count: 4 }
  5. 결국 이렇게 바뀌는 거야:
set((state) => ({ count: state.count + 1 }))
→ set(() => ({ count: 4 }))
→ 저장됨

 

🔧 한눈에 이해하는 비유

상태(State)는 '기억'이라고 생각하면 쉬워.
지금 앱이 "count라는 숫자"를 기억하고 있는데, 그걸 조금 바꿔서 다시 기억시키는 거야.

📦 예시 비유:

  • state.count는 "현재 기억하고 있는 숫자"
  • state.count + 1은 "그걸 1 더한 새 숫자"
  • set(...)은 "기억을 바꾸는 행동"
[ 현재 상태: { count: 3 } ]
       |
       V
set((state) => ({ count: state.count + 1 }))
       |
       V
[ 새로운 상태: { count: 4 } ]

 

 

 

 

const count = useCounterStore((state) => state.count);
const increase = useCounterStore((state) => state.increase);
const reset = useCounterStore((state) => state.reset);

🧠 이해용 표: 이 코드는 뭐 하는 건가요?

코드하는 일결과값 예시
useCounterStore((state) => state.count) 현재 숫자를 가져옴 3
useCounterStore((state) => state.increase) 숫자를 1 올리는 함수 가져옴 increase() 함수
useCounterStore((state) => state.reset) 숫자를 0으로 초기화하는 함수 가져옴 reset() 함수
 

📦 쉬운 비유:

useCounterStore는 "zustand 저장소 창고에서 필요한 걸 꺼내오는 도구"야.

  • count → 현재 숫자 상태를 꺼내옴.
  • increase → 숫자를 +1 해주는 버튼 도구를 꺼내옴.
  • reset → 0으로 바꾸는 리셋 도구를 꺼내옴.

2️⃣ 버튼 코드(onClick={...})가 뭔지 이해해보자

이 코드:

<button onClick={increase}>+1 증가</button>
<button onClick={reset}>리셋</button>

📘 표로 설명

코드하는 일실제 동작
onClick={increase} 버튼을 누르면 increase() 실행 숫자 +1
onClick={reset} 버튼을 누르면 reset() 실행 숫자 0으로 초기화
 

🎬 전체 흐름 예시

  1. 페이지를 열면 숫자 상태(count)가 3이라고 가정
  2. +1 증가 버튼을 클릭하면 → increase()가 실행됨 → count가 4가 됨
  3. 리셋 버튼 클릭 → reset() 실행 → count가 0이 됨