Next.js 15 Fullstack Web Apps · 강의

Zustand/Jotai를 사용한 클라이언트 측 상태

Zustand 또는 Jotai를 사용하여 가볍고 성능이 뛰어난 클라이언트 측 전역 상태 관리를 구현합니다.

레슨 2/411개 단계

Zustand/Jotai를 사용한 클라이언트 측 상태은(는) CoddyKit의 무료 Next.js 15 Fullstack Web Apps 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Next.js 15 Fullstack Web Apps 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Next.js 15 Fullstack Web Apps 강의에는 총 4개의 강의가 포함되어 있습니다.

이 강의의 일부는 아직 번역되지 않았으며 영어로 표시됩니다.

Global State: Beyond Local

In React, you've learned about local state with useState, which is great for data used only within a single component.

But what if data needs to be shared across many components, or deeply nested components, without 'prop drilling' (passing props down through many layers)? This is where client-side global state management comes in.

Global state allows any component to access or update shared data directly, simplifying complex data flows and making your application more maintainable.

Meet Zustand: Simple State

Zustand is a small, fast, and scalable state management solution for React. Its API is simple and hooks-based, making it very intuitive to learn and use.

  • Minimalistic: Less boilerplate code.
  • Fast: Optimized for performance.
  • Flexible: Works with any React component.
  • Hooks-based: Feels natural to React developers.

Get Started with Zustand

Before we dive into creating stores, you'll need to install Zustand in your Next.js project. It's a simple npm or yarn command.

Open your terminal in the project root and run:

npm install zustand

Or if you prefer Yarn:

yarn add zustand

Once installed, you're ready to define your first store!

Crafting a Zustand Store

A Zustand store is created using the create function. This function takes a callback that defines your initial state and actions.

Think of a store as a central hub for specific pieces of global data. Let's create a basic counter store:

import { create } from 'zustand';

// Define your store
const useCounterStore = create((set) => ({
  count: 0,
}));

// This store can be imported and used in your React components.
// It's not runnable on its own, but defines the global state structure.

Store State & Actions

Beyond just holding state, a store also contains actions – functions that modify the state. The set function provided by Zustand allows you to update the store's state.

Here's how we add increment and decrement actions to our counter store:

import { create } from 'zustand';

const useCounterStore = create((set) => ({
  count: 0,
  // Action to increment count
  increment: () => set((state) => ({ count: state.count + 1 })),
  // Action to decrement count
  decrement: () => set((state) => ({ count: state.count - 1 })),
}));

// This store now has both state (count) and actions (increment, decrement).

Connect Components to Store

To use the global state in your React components, you simply import the store hook (e.g., useCounterStore) and call it. You can select specific pieces of state or actions.

Let's create a component that displays the current count from our store:

import { create } from 'zustand';

// Define your store (as in previous scenes)
const useCounterStore = create((set) => ({
  count: 0,
  increment: () => set((state) => ({ count: state.count + 1 })),
  decrement: () => set((state) => ({ count: state.count - 1 })),
}));

// A React component that uses the store
export default function CounterDisplay() {
  // Select the 'count' state from the store
  const count = useCounterStore((state) => state.count);

  return (
    <div>
      <p>Current Count: {count}</p>
    </div>
  );
}

// This component can be rendered in a Next.js page or another component.

Interactive Counter Example

Now let's make our counter interactive! We'll add buttons that call the increment and decrement actions defined in our store.

This shows how components can both read from and write to the global state, keeping everything synchronized.

import { create } from 'zustand';

// Define your store
const useCounterStore = create((set) => ({
  count: 0,
  increment: () => set((state) => ({ count: state.count + 1 })),
  decrement: () => set((state) => ({ count: state.count - 1 })),
}));

// A React component that uses the store and its actions
export default function InteractiveCounter() {
  // Select both state and actions
  const { count, increment, decrement } = useCounterStore();

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={decrement}>Decrement</button>
      <button onClick={increment}>Increment</button>
    </div>
  );
}

// This component is fully runnable and demonstrates Zustand in action.

Efficient State Selection

By default, if any part of the store's state changes, components that use the store might re-render. To optimize this, you can use selectors.

A selector is a function you pass to useStore that picks only the specific data your component needs. If only that selected data changes, the component re-renders.

import { create } from 'zustand';

// A more complex store with multiple states
const useSettingsStore = create((set) => ({
  theme: 'dark',
  fontSize: 16,
  toggleTheme: () => set((state) => ({ theme: state.theme === 'dark' ? 'light' : 'dark' })),
  setFontSize: (size) => set({ fontSize: size }),
}));

// Component only cares about 'theme'
export default function ThemeDisplay() {
  // Using a selector to only subscribe to 'theme'
  const theme = useSettingsStore((state) => state.theme);

  return (
    <p>Current Theme: <b>{theme}</b></p>
  );
}

// If fontSize changes, ThemeDisplay will NOT re-render because it only selects 'theme'.

Zustand Best Practices

To keep your Zustand stores clean and efficient:

  • Immutability: Always update state immutably. Don't directly modify objects or arrays in state; create new ones.
  • Separate Concerns: Keep related state and actions in the same store. Create multiple stores for different domains (e.g., useUserStore, useCartStore).
  • Selectors: Use selectors to prevent unnecessary re-renders in components.
  • Middleware: For advanced features like persistence or logging, explore Zustand's middleware options.

Zustand Knowledge Check

Zustand offers a flexible and lightweight approach to global state management. Based on what you've learned, choose the correct statements about its benefits and characteristics.

Zustand: A Quick Recap

Congratulations! You've learned the fundamentals of client-side global state management with Zustand.

  • We explored why global state is essential for complex apps.
  • You saw how to define a Zustand store with state and actions using create.
  • We learned to connect React components to the store and interact with its state and actions.
  • Finally, we discussed how selectors can optimize component re-renders.

Zustand empowers you to manage shared data efficiently, making your Next.js applications more scalable and easier to maintain.

무료로 시작

AI 튜터와 함께 TypeScript을(를) 배우세요 — 무료

브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.

코스
12
레슨
48

자주 묻는 질문

“Zustand/Jotai를 사용한 클라이언트 측 상태” 강의는 무료인가요?

네 — “Zustand/Jotai를 사용한 클라이언트 측 상태” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Next.js 15 Fullstack Web Apps 강의 전체를 잠금 해제할 수 있습니다. Next.js 15 Fullstack Web Apps 강의에는 총 4개의 강의가 포함되어 있습니다.

“Zustand/Jotai를 사용한 클라이언트 측 상태”에서 뭘 배우나요?

Zustand 또는 Jotai를 사용하여 가볍고 성능이 뛰어난 클라이언트 측 전역 상태 관리를 구현합니다. 브라우저에서 직접 실행하는 실습 코드로 Next.js 15 Fullstack Web Apps을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Next.js 15 Fullstack Web Apps을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Next.js 15 Fullstack Web Apps은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.

“Zustand/Jotai를 사용한 클라이언트 측 상태” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Next.js 15 Fullstack Web Apps 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Next.js 15 Fullstack Web Apps 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 서버 상태를 위한 React Query
  2. Zustand/Jotai를 사용한 클라이언트 측 상태
  3. 서버 측 캐싱 전략
  4. 낙관적 업데이트와 캐시 무효화
← Next.js 15 Fullstack Web Apps(으)로 돌아가기