사용법
설치
yarn add zustand
store 생성
1) zustand 폴더 > bearsStore.js 생성
2) zustand의 create를 사용해 스토어 생성 (이 때 스토어는 관리할 상태에 따라 여러개가 될 수 있음)
import { create } from 'zustand';
const useBearStore = create((set) => {
  return {
    bears: 0,
    increase: function() {
      set(function(state) {
        return {
          bears: state.bears + 1
        }
      })
    },
    // 초기화용 함수
    init: function (){
      set({
        bears: 0,
      })
    }
  }
});
store를 받아와 사용
const App = () {
  const bears = useBearsStore(function(state) {
    return state.bears;
  });
  
  const increase = useBearsStore(function(state){
    return state.increase;
  });
  
  // 혹은 구조분해할당 활용
  const { bears, increase } = useBearsStore(function(state){
    return state;
  });
  
  return (
    <div>
      <h2>{ bears }</h2>
      <button onClick={ increase }> +1 </button>
    </div>
  )
}
immer 사용해 불변성 유지하기

위 예시는 불변성을 어기는 예시로, 구조분해할당/map/filter 등 새로운 배열이나 객체를 반환하는 방법을 사용하는 방법과 immer를 활용하는 방법을 사용할 수 있다.
설치
yarn add immer
store의 set을 immer로 감싸주기
import { immer } from 'zustand/middleware/immer'
const useTodoStore = create(immer(set) => { ... })이렇게 사용하고 위 캡쳐 예시처럼 push 등을 활용해 불변성을 지키지 않는 것처럼 코드를 작성해도 내부적으로 처리를 해준다
persist 사용해 새로고침시에도 데이터 유지하기
immer를 감싸거나, immer를 사용하지 않는 경우라면 store를 만들 때 set 부분을 감싸주고 함수가 끝나는 부분에 로컬 혹은 세션 스토리지에 저장할 이름(name)을 지정해줘야 함
import { produce } from "immer";
import { create } from "zustand";
import { persist } from "zustand/middleware";
const useTodosStore = create(
  persist(
    (set) => ({
      todos: [
        {
          id: 1,
          title: "Learn Zustand",
          tasks: [{ id: 1, task: "Read documentation", done: false }],
        },
      ],
      addTask: (todoId, newTask) =>
        set(
          produce((state) => {
            const todo = state.todos.find((todo) => todo.id === todoId);
            if (todo) {
              todo.tasks.push(newTask); // 불변성 깨짐: 직접 수정
            }
            // return { todos: state.todos }; // 변경된 참조가 기존 상태와 같아 리렌더링되지 않음
          })
        ),
      toggleTask: (todoId, taskId) =>
        set(
          produce((state) => {
            const todo = state.todos.find((todo) => todo.id === todoId);
            if (todo) {
              const task = todo.tasks.find((task) => task.id === taskId);
              if (task) {
                task.done = !task.done; // 불변성 깨짐: 직접 수정
              }
            }
            // return { todos: state.todos }; // 변경된 참조가 기존 상태와 같아 리렌더링되지 않음
          })
        ),
    }),
    {
      name: "todos-storage", // 저장소 이름을 설정해요!
      // getStorage: () => sessionStorage, // localStorage가 아닌 곳에 저정하고 싶다면!
    }
  )
);
export default useTodosStore;'React' 카테고리의 다른 글
| [TanStack Query] useQuery() 옵션 - enabled, select (0) | 2024.09.06 | 
|---|---|
| UX 향상 기법 - Throttling & Debouncing, lodash (1) | 2024.09.06 | 
| Tanstack Query 캐시데이터의 생명주기 (0) | 2024.09.05 | 
| TanStack Query (0) | 2024.09.05 | 
| [React] 비동기 작업, HTTP (0) | 2024.09.05 | 
