Zustand는 React의 상태 관리 라이브러리 tjfaudwha

1 답변

0 투표

[React] Zustand 상태 관리 라이브러리

Tags: React · Zustand


Zustand(체어트)는 독일어로 ‘상태’라는 뜻을 가지고 있으며, React 애플리케이션에서 전역 상태 관리를 간편하게 할 수 있도록 도와주는 라이브러리입니다. Context API를 기반으로 동작하면서도 React에 직접 의존하지 않아, 잦은 상태 변경이 필요한 곳에서도 퍼포먼스를 유지할 수 있고, Redux 대비 훨씬 적은 코드량으로 구현이 가능합니다.


Zustand 설치

터미널에서 아래 명령어 중 하나를 실행하여 설치하세요.


# npm

npm install zustand

# yarn

yarn add zustand

⸻

 Zustand 사용 방법

Zustand의 핵심은 create 함수입니다. 이 함수를 통해 스토어(store) 를 생성하고, 상태(state)와 상태를 갱신하는 액션(action)을 정의할 수 있습니다. 생성된 스토어는 훅(hook) 형태로 내보내져, 컴포넌트 어디서든 간단히 불러와 사용할 수 있습니다.

1) store.ts

import { create } from 'zustand';

interface Todo { id: number; text: string; }

interface TodoStore { todos: Todo[]; addTodo: (todo: Todo) => void; removeTodo: (todoId: number) => void; }

const useTodoStore = create((set) => ({ todos: [], // 새로운 Todo를 추가하는 액션 addTodo: (todo) => set((state) => ({ todos: [...state.todos, todo], })), // 특정 Todo를 ID로 삭제하는 액션 removeTodo: (todoId) => set((state) => ({ todos: state.todos.filter((todo) => todo.id !== todoId), })), }));

export default useTodoStore;

• create(…) 에 제네릭으로 상태와 액션의 타입을 지정합니다. • set 함수는 불변성을 유지하면서 상태를 업데이트합니다.


⸻

2) TodoList.tsx

import useTodoStore from './store';

export default function TodoList() { // 스토어에서 todos 배열과 removeTodo 액션을 가져옵니다. const { todos, removeTodo } = useTodoStore();

// subscribe로 상태 변경 시마다 로그를 출력할 수도 있습니다. useTodoStore.subscribe((state) => console.log('현재 todos:', state.todos));

return (

## Todo

*   {todos.map((todo) => (
*   {todo.text}removeTodo(todo.id)}>Delete
*   ))}

); }

• useTodoStore() 에서 반환된 객체를 구조 분해 할당하여 사용합니다. • subscribe 메서드로 특정 리스너를 등록하면, 상태가 바뀔 때마다 콜백이 호출됩니다.


⸻

3) TodoForm.tsx

import { FormEvent, ChangeEvent, useState } from 'react'; import useTodoStore from './store';

export default function TodoForm() { const [text, setText] = useState(''); const { addTodo } = useTodoStore();

// 폼 제출 시 새로운 Todo를 추가 const handleSubmit = (e: FormEvent) => { e.preventDefault(); if (!text.trim()) return;

addTodo({ id: Date.now(), text }); setText('');


};

// 입력 값 변화 시 상태 업데이트 const handleChange = (e: ChangeEvent) => { setText(e.target.value); };

return (

Add

); }

• useState로 로컬 입력 상태를 관리하고, 제출 시 스토어의 addTodo를 호출합니다. • Date.now()를 사용해 간단히 고유 ID를 생성합니다.


⸻

 Zustand 동작 원리

Zustand는 내부적으로 createStoreImpl이라는 함수로 스토어를 구현합니다. 주요 로직은 다음과 같습니다:

const createStoreImpl: CreateStoreImpl = (createState) => { type TState = ReturnType; type Listener = (state: TState, prevState: TState) => void;

// 현재 상태를 보관하는 변수 let state: TState; // 리스너(구독자)들을 보관하는 Set const listeners: Set = new Set();

// 상태를 변경하는 함수: partial은 변경될 부분, replace는 전체 교체 여부 const setState: StoreApi['setState'] = (partial, replace) => { // 함수형(updater) 또는 객체형 partial 처리 const nextState = typeof partial === 'function' ? (partial as (state: TState) => TState)(state) : partial;

// 변경된 상태가 이전과 다를 때만 업데이트 if (!Object.is(nextState, state)) { const previousState = state; state = replace ?? (typeof nextState !== 'object' || nextState === null) ? (nextState as TState) // 전체 교체 : Object.assign({}, state, nextState); // 부분적 병합

// 모든 리스너에 변경 전∙후 상태 전달 listeners.forEach((listener) => listener(state, previousState)); }


};

// 현재 상태 반환 const getState: StoreApi['getState'] = () => state;

// 초기 상태 반환 const getInitialState: StoreApi['getInitialState'] = () => initialState;

// 구독 등록 함수 const subscribe: StoreApi['subscribe'] = (listener) => { listeners.add(listener); // 언구독 함수 반환 return () => listeners.delete(listener); };

// 스토어 API 반환 return { setState, getState, getInitialState, subscribe }; };
  1. state: 현재 상태를 보관하는 변수
  2. listeners: 상태 변경을 구독(subscribe)한 콜백들의 모음
  3. setState: 불변성을 유지하며 상태를 갱신하고, 변경된 경우에만 구독자에게 알림
  4. getState/getInitialState: 각각 현재 상태와 생성 시 초기 상태를 반환
  5. subscribe: 리스너 등록 및 해제 기능 제공 ```

구로역 맛집 시흥동 맛집
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
add
...