본문 바로가기

React.js/상태관리

React에서 zustand 써보기 2(비동기처리, 스토리지저장, 데브툴즈)

반응형
SMALL

어제 저녁까지 공부한 내용인데, zustand가 사용성이 굉장히 좋은 것 같다.

recoil아니면 zustand가 사용성도 좋고, react 문법과 구조도 비슷해서 편리한 것 같다.

솔직히 근본은 redux라고 하던데, redux는 너무 복잡하게 느껴진다.

 

아무튼, 이번글에서는 zustand에서 다양한 기능들을 알아볼 것이다.

지난번글에서는 zustand를 이용해서 store를 만들고, 저장하고, 가져와서 사용했었는데,

실제로는 더 다양한 기능들이 있겠지만, 기본적인 기능들을 알아보도록하자.

 

1. 스토리지저장

스토리지저장은 persist라는 메소드를 사용하면 된다.

persist는 zustand/middleware 안에 있고, zustand 설치했으면 그냥 사용할 수 있다.

 - 사용법은 zustand로 만든 store전체를 감싸주는게 방법이다.

 - 그리고, 두번째 매개변수를 꼭 넣어줘야한다. 언제부터 바뀐지는 모르겠지만, 현재 버전(4.5.1)에서는 안되더라

 - 두번째 매개변수에 들어갈 수 있는 것들은 다양한 것들이 있는데, 기본적으로 name이라는 속성을 넣어줘야 storage에 들어갈 때 이름이 생긴다. 안넣으면 undefined로 나온다.

 - 다른 속성도 넣으면 저장되는 스토리지를 정할 수 있는 등등 기능이 추가된다.

import { create } from "zustand";
import { devtools, persist } from "zustand/middleware";

let todoStore = (set) => ({
  todos: [],
  addTodo: (todoText) =>
    set(state => ({
      todos: [
        ...state.todos,
        {
          text: todoText,
          id: getId(),
          isCompleted: false
        }
      ]
    })),
  deleteTodo: (todoId) =>
    set(state => ({
      todos: state.todos.filter((todo) => todo.id !== todoId)
    })),
  completeTodo: (todoId) =>
    set(state => ({
      todos: state.todos.map((todo) => {
        if(todo.id === todoId) {
          return {
            ...todo,
            isCompleted: true
          }
        }
        return todo;
      })
    }))
})

todoStore = devtools(todoStore);
todoStore = persist(todoStore, {name: 'todo'});

export const useTodoStore = create(todoStore);


let id = 0;
function getId() {
  return id++;
}

2. 스토리지 삭제

스토리지에 저장했으면 지울수도 있어야한다.

지우는 방법은 아래와 같다.

 - 스토리지이름.persist.clearStorage(); 하면 스토리지에 저장된 데이터가 다 날라간다.

import React from 'react'
import { useConterStore } from '../store/useCounterStore';

const Counter = () => {
  const { count, increment, reset, setNumber } = useConterStore();

  const clear = () => {
    useConterStore.persist.clearStorage();  
    // store이름 하나 잡고 persist.clearStorage() 하면 storage 다 날라감, value만 사라지는게 아니라 그냥 다 사라짐
  }
  return (
    <div>
      <p>{count}</p>
      <button onClick={increment}>one up</button>
      <button onClick={reset}>reset</button>
      <button onClick={() => setNumber(3)}>set number</button>
      <button onClick={clear}>clear</button>
    </div>
  )
}

export default Counter

3. redux devtools 사용하기

zustand는 redux devtools 를 사용할 수 있다.

redux 쓰는 이유가 사실 devtools 쓰려고 하는거라고 개인적으로 생각하는데,

이거 쓸수 있으니까 어려운 redux안써도 될 듯

devtools도 zustand/middleware안에 있다.

사용법은 아래와 같다.

 - devtools 메소드에 store변수를 넣어주면 끝이다.

import { create } from "zustand";
import { devtools, persist } from 'zustand/middleware'

let counterStore = (set) => ({
  count: 0,
  increment: () => set((state) => ({ count: state.count + 1 })),
  reset: () => set({count: 0}),
  setNumber: (number) => set({count: number})
});

counterStore = devtools(counterStore);
counterStore = persist(counterStore, {name: 'counter'});

export const useConterStore = create(counterStore);

4. 비동기 처리하기

비동기 처리하는 방법은 앞에서 정리한 내용들을 기억한다면 별거없다.

react 기본 내장 fetch를 사용했다.

async, await 이용해서 fetch함수를 store안에 만들었다.

import { create } from "zustand";

export const useUserStore = create((set) => ({
  user: {},
  fetch: async (id) => {
    const response = await fetch(path);
    set({user: await response.json()});
  }
}));

구조분해할당으로 store가져오고, fetch는 useEffect안에 콜백으로 넣었다.

그러면 store안에 user에 id: 1에 대한 유저데이터 전체가 들어갔고, 객체형태라서 그냥 쓸 수 있다.

import { useEffect } from 'react';
import './App.css';
import Counter from './components/Counter';
import TodoList from './components/TodoList';
import { useUserStore } from './store/useUserStore';

function App() {
  const {fetch, user} = useUserStore();
  console.log(user);

  useEffect(() => {
    fetch(1);
  },[fetch]);

  return (
    <div className="App">
      <header className='App-header'>
        <Counter />
        <TodoList />
        <p>
          {user.name}
        </p>
        <p>
          {user.phone}
        </p>
      </header>
    </div>
  );
}

export default App;

 

전체 만들어진거 코드 구경하기

 - 이전 글에 있던 repository에 새로운 버전으로 만들어뒀다.

https://github.com/jmpark24/react-zustand-app

 

GitHub - jmpark24/react-zustand-app

Contribute to jmpark24/react-zustand-app development by creating an account on GitHub.

github.com

이렇게 생겼다. 기능들도 잘 돌아간다.

반응형
LIST