React/Zustand

Zustand를 활용(10): 상태 지속성 관리 (Persist)

atomicdev 2024. 10. 15. 13:57
728x90

프로젝트 상태 관리 실습 - 간단한 예제 개발

내용:

  • 이번 강의에서는 Zustand로 상태 관리를 적용한 간단한 프로젝트를 직접 개발해봅니다.
  • 상태 모듈화, 비동기 처리, 상태 지속성 관리, 성능 최적화 등 상태 관리의 다양한 기법을 종합적으로 활용합니다.
    상태를 관리하는 Zustand 프로젝트 흐름

 

실습 예제: 간단한 Todo 리스트 애플리케이션

Step 1: 프로젝트 설정

  1. Create React App으로 새 프로젝트 생성
    npx create-react-app todo-app
    cd todo-app
    npm install zustand
  2. Zustand 설치 및 기본 설정
    • zustand 라이브러리를 설치하고, 상태 저장소(store)를 설정합니다.

 

Step 2: 상태 저장소 구성 (Zustand 사용)

  1. store.js 파일 생성:
    import create from 'zustand';
    
    // Zustand 상태 저장소
    const useStore = create((set) => ({
      todos: [],
      addTodo: (newTodo) => set((state) => ({ todos: [...state.todos, newTodo] })),
      removeTodo: (todoToRemove) => set((state) => ({
        todos: state.todos.filter((todo) => todo !== todoToRemove)
      })),
    }));
    
    export default useStore;

 

Step 3: 컴포넌트 작성

  1. TodoList.js 작성:
    import React from 'react';
    import useStore from './store';
    
    function TodoList() {
      const todos = useStore((state) => state.todos);
      const removeTodo = useStore((state) => state.removeTodo);
    
      return (
        <ul>
          {todos.map((todo, index) => (
            <li key={index}>
              {todo}
              <button onClick={() => removeTodo(todo)}>삭제</button>
            </li>
          ))}
        </ul>
      );
    }
    
    export default TodoList;
  2. TodoInput.js 작성:
    import React, { useState } from 'react';
    import useStore from './store';
    
    function TodoInput() {
      const [newTodo, setNewTodo] = useState('');
      const addTodo = useStore((state) => state.addTodo);
    
      const handleAddTodo = () => {
        addTodo(newTodo);
        setNewTodo('');
      };
    
      return (
        <div>
          <input
            type="text"
            value={newTodo}
            onChange={(e) => setNewTodo(e.target.value)}
          />
          <button onClick={handleAddTodo}>추가</button>
        </div>
      );
    }
    
    export default TodoInput;

 

 

Step 4: 애플리케이션 연결

  1. App.js 수정:
    import React from 'react';
    import TodoList from './TodoList';
    import TodoInput from './TodoInput';
    
    function App() {
      return (
        <div>
          <h1>Todo 리스트</h1>
          <TodoInput />
          <TodoList />
        </div>
      );
    }
    
    export default App;

 

Step 5: 비동기 API 통합

  1. store.js에 비동기 API 호출 추가:
    const useStore = create((set) => ({
      todos: [],
      fetchTodos: async () => {
        const response = await fetch('https://jsonplaceholder.typicode.com/todos?_limit=5');
        const data = await response.json();
        set({ todos: data.map((item) => item.title) });
      },
      addTodo: (newTodo) => set((state) => ({ todos: [...state.todos, newTodo] })),
      removeTodo: (todoToRemove) => set((state) => ({
        todos: state.todos.filter((todo) => todo !== todoToRemove),
      })),
    }));
  2. TodoList.js에서 API 데이터 호출:
    import React, { useEffect } from 'react';
    import useStore from './store';
    
    function TodoList() {
      const todos = useStore((state) => state.todos);
      const fetchTodos = useStore((state) => state.fetchTodos);
      const removeTodo = useStore((state) => state.removeTodo);
    
      useEffect(() => {
        fetchTodos();
      }, [fetchTodos]);
    
      return (
        <ul>
          {todos.map((todo, index) => (
            <li key={index}>
              {todo}
              <button onClick={() => removeTodo(todo)}>삭제</button>
            </li>
          ))}
        </ul>
      );
    }
    
    export default TodoList;

 

 

Step 6: 상태 영속성 추가 (Persist)

  1. store.js에 상태를 로컬 스토리지에 저장하는 로직 추가:
    import create from 'zustand';
    import { persist } from 'zustand/middleware';
    
    const useStore = create(
      persist(
        (set) => ({
          todos: [],
          addTodo: (newTodo) => set((state) => ({ todos: [...state.todos, newTodo] })),
          removeTodo: (todoToRemove) => set((state) => ({
            todos: state.todos.filter((todo) => todo !== todoToRemove),
          })),
        }),
        { name: 'todo-storage' } // 로컬 스토리지 키
      )
    );
    
    export default useStore;

 

Step 7: 최종 테스트

  • 상태 업데이트, 로컬 스토리지에 상태 저장 및 복구, API 데이터 처리 등을 종합적으로 테스트합니다.

학습 목표:

  • Zustand를 활용하여 상태 관리를 실습하며, 상태 모듈화, 비동기 처리, 상태 영속성을 이해하고 구현할 수 있습니다.
728x90