이미지 로딩 중...

Next.js Zustand 상태관리 완벽 가이드 - 슬라이드 1/13
C

CodeDeck AI

2025. 11. 8. · 1 Views

Next.js Zustand 상태관리 완벽 가이드

Next.js 프로젝트에서 Zustand를 사용한 전역 상태 관리 방법을 단계별로 학습합니다. 설치부터 실전 활용까지 초급자도 쉽게 따라할 수 있는 예제로 구성되어 있습니다.


카테고리:React
언어:TypeScript
난이도:intermediate
메인 태그:#Next.js
서브 태그:
#Zustand#StateManagement#GlobalState#TypeScript

들어가며

이 글에서는 Next.js Zustand 상태관리 완벽 가이드에 대해 상세히 알아보겠습니다. 총 12가지 주요 개념을 다루며, 각각의 개념에 대한 설명과 실제 코드 예제를 함께 제공합니다.

목차

  1. Zustand_설치_및_기본_스토어_생성
  2. 컴포넌트에서_스토어_사용하기
  3. TypeScript로_타입_안전한_스토어_만들기
  4. 여러_상태를_관리하는_실전_스토어
  5. Next.js에서_지속성_추가하기_persist
  6. 비동기_액션_처리하기
  7. 스토어_분리하고_결합하기
  8. 셀렉터로_성능_최적화하기
  9. Next.js_App_Router에서_사용하기
  10. 액션_외부에서_호출하기
  11. 개발자_도구_연동하기_devtools
  12. 초기_상태_리셋하기

1. Zustand_설치_및_기본_스토어_생성

개요

Zustand를 설치하고 가장 기본적인 상태 스토어를 생성하는 방법입니다. create 함수로 스토어를 만들고 상태와 액션을 정의합니다.

코드 예제

import { create } from 'zustand'

const useStore = create((set) => ({
  count: 0,
  increment: () => set((state) => ({ count: state.count + 1 })),
  decrement: () => set((state) => ({ count: state.count - 1 })),
}))

설명

create 함수로 스토어를 만들고, set 함수를 사용해 상태를 업데이트하는 액션을 정의합니다. 매우 간단한 구조로 Redux보다 훨씬 적은 코드로 상태 관리가 가능합니다.


2. 컴포넌트에서_스토어_사용하기

개요

생성한 Zustand 스토어를 React 컴포넌트에서 사용하는 방법입니다. 훅처럼 간단하게 호출하여 상태와 액션에 접근할 수 있습니다.

코드 예제

export default function Counter() {
  const count = useStore((state) => state.count)
  const increment = useStore((state) => state.increment)

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>증가</button>
    </div>
  )
}

설명

useStore 훅으로 필요한 상태와 액션만 선택적으로 가져올 수 있습니다. 셀렉터 함수를 사용하면 불필요한 리렌더링을 방지할 수 있습니다.


3. TypeScript로_타입_안전한_스토어_만들기

개요

TypeScript를 사용하여 타입 안전성을 보장하는 Zustand 스토어를 만드는 방법입니다. 인터페이스로 스토어의 구조를 명확히 정의합니다.

코드 예제

interface CounterStore {
  count: number
  increment: () => void
  decrement: () => void
}

const useCounterStore = create<CounterStore>((set) => ({
  count: 0,
  increment: () => set((state) => ({ count: state.count + 1 })),
  decrement: () => set((state) => ({ count: state.count - 1 })),
}))

설명

인터페이스로 스토어의 타입을 정의하고 제네릭으로 전달하면, 타입 추론과 자동완성이 완벽하게 작동합니다.


4. 여러_상태를_관리하는_실전_스토어

개요

사용자 정보와 로그인 상태를 관리하는 실전 예제입니다. 여러 상태와 액션을 하나의 스토어에서 관리할 수 있습니다.

코드 예제

interface User {
  id: string
  name: string
}

const useAuthStore = create<{
  user: User | null
  isLoggedIn: boolean
  login: (user: User) => void
  logout: () => void
}>((set) => ({
  user: null,
  isLoggedIn: false,
  login: (user) => set({ user, isLoggedIn: true }),
  logout: () => set({ user: null, isLoggedIn: false }),
}))

설명

복잡한 객체 상태와 관련 액션들을 하나의 스토어로 묶어 관리합니다. 로그인/로그아웃 로직을 중앙에서 관리하여 코드 재사용성이 높아집니다.


5. Next.js에서_지속성_추가하기_persist

개요

새로고침해도 상태가 유지되도록 localStorage에 자동 저장하는 기능입니다. Zustand의 persist 미들웨어를 사용합니다.

코드 예제

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

const useStore = create(
  persist(
    (set) => ({
      theme: 'light',
      setTheme: (theme: string) => set({ theme }),
    }),
    { name: 'theme-storage' }
  )
)

설명

persist 미들웨어로 스토어를 감싸면 자동으로 localStorage에 저장됩니다. 페이지를 새로고침해도 상태가 유지됩니다.


6. 비동기_액션_처리하기

개요

API 호출과 같은 비동기 작업을 Zustand에서 처리하는 방법입니다. async/await를 사용하여 로딩 상태도 함께 관리합니다.

코드 예제

const useDataStore = create<{
  data: any[]
  isLoading: boolean
  fetchData: () => Promise<void>
}>((set) => ({
  data: [],
  isLoading: false,
  fetchData: async () => {
    set({ isLoading: true })
    const response = await fetch('/api/data')
    const data = await response.json()
    set({ data, isLoading: false })
  },
}))

설명

액션 함수를 async로 만들어 비동기 작업을 처리하고, 로딩 상태를 함께 업데이트합니다. API 호출 전후로 상태를 관리할 수 있습니다.


7. 스토어_분리하고_결합하기

개요

기능별로 스토어를 분리한 후 필요할 때 결합하여 사용하는 패턴입니다. 코드 구조가 깔끔해지고 유지보수가 쉬워집니다.

코드 예제

const createUserSlice = (set) => ({
  user: null,
  setUser: (user) => set({ user }),
})

const createCartSlice = (set) => ({
  items: [],
  addItem: (item) => set((state) => ({
    items: [...state.items, item]
  })),
})

const useStore = create((...a) => ({
  ...createUserSlice(...a),
  ...createCartSlice(...a),
}))

설명

각 기능을 별도의 함수로 분리하고 스프레드 연산자로 결합합니다. 대규모 프로젝트에서 상태 관리 코드를 모듈화할 수 있습니다.


8. 셀렉터로_성능_최적화하기

개요

필요한 상태만 구독하여 불필요한 리렌더링을 방지하는 방법입니다. 얕은 비교로 성능을 최적화합니다.

코드 예제

import { shallow } from 'zustand/shallow'

function TodoList() {
  const { todos, addTodo } = useStore(
    (state) => ({
      todos: state.todos,
      addTodo: state.addTodo
    }),
    shallow
  )

  return <div>{todos.map(todo => <p>{todo}</p>)}</div>
}

설명

shallow 비교를 사용하면 선택한 값이 실제로 변경될 때만 리렌더링됩니다. 여러 값을 한 번에 선택할 때 성능이 향상됩니다.


9. Next.js_App_Router에서_사용하기

개요

Next.js 13+ App Router에서 Zustand를 사용하는 방법입니다. 클라이언트 컴포넌트로 명시하여 사용합니다.

코드 예제

'use client'

import { useStore } from '@/store/useStore'

export default function ClientComponent() {
  const count = useStore((state) => state.count)
  const increment = useStore((state) => state.increment)

  return <button onClick={increment}>Count: {count}</button>
}

설명

'use client' 지시어를 추가하여 클라이언트 컴포넌트임을 명시합니다. Zustand는 클라이언트 사이드 상태 관리 라이브러리이므로 서버 컴포넌트에서는 사용할 수 없습니다.


10. 액션_외부에서_호출하기

개요

컴포넌트 외부나 유틸리티 함수에서 스토어의 액션을 호출하는 방법입니다. getState로 현재 상태에 접근할 수 있습니다.

코드 예제

const useStore = create((set, get) => ({
  count: 0,
  increment: () => set({ count: get().count + 1 }),
}))

// 컴포넌트 외부에서 호출
export function incrementFromOutside() {
  useStore.getState().increment()
}

설명

useStore.getState()로 스토어의 현재 상태와 액션에 접근할 수 있습니다. API 유틸리티나 이벤트 핸들러에서 유용하게 사용됩니다.


11. 개발자_도구_연동하기_devtools

개요

Redux DevTools를 Zustand와 연동하여 상태 변화를 시각적으로 디버깅하는 방법입니다.

코드 예제

import { devtools } from 'zustand/middleware'

const useStore = create(
  devtools(
    (set) => ({
      count: 0,
      increment: () => set((state) => ({ count: state.count + 1 })),
    }),
    { name: 'CounterStore' }
  )
)

설명

devtools 미들웨어를 추가하면 Redux DevTools에서 Zustand 상태를 모니터링할 수 있습니다. 상태 변화 추적과 타임 트래블 디버깅이 가능합니다.


12. 초기_상태_리셋하기

개요

스토어의 상태를 초기값으로 되돌리는 리셋 기능을 구현하는 방법입니다. 로그아웃이나 초기화가 필요할 때 유용합니다.

코드 예제

const initialState = { count: 0, user: null }

const useStore = create((set) => ({
  ...initialState,
  increment: () => set((state) => ({ count: state.count + 1 })),
  reset: () => set(initialState),
}))

// 사용: useStore.getState().reset()

설명

초기 상태를 별도 변수로 분리하고 reset 액션을 만들어 언제든 초기화할 수 있습니다. 사용자 로그아웃 시 모든 상태를 한 번에 정리할 때 편리합니다. --- 이상으로 Next.js에서 Zustand를 활용한 상태 관리 가이드를 마칩니다. 각 카드의 코드를 직접 실행해보며 학습하시면 더욱 효과적입니다!


마치며

이번 글에서는 Next.js Zustand 상태관리 완벽 가이드에 대해 알아보았습니다. 총 12가지 개념을 다루었으며, 각각의 사용법과 예제를 살펴보았습니다.

관련 태그

#Next.js #Zustand #StateManagement #GlobalState #TypeScript

#Next.js#Zustand#StateManagement#GlobalState#TypeScript#React

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.