새로운 프로젝트 세팅을 하면서 어떤 상태관리 라이브러리를 쓸까 생각을 해보았다. 그 전에는 쌩 리덕스를 쓰고 있어서 보일러플레이트 코드가 매우 많이 필요했다. 그래서 비교적 쉽고 보일러플레이트가 적은 recoil을 쓰려고 했는데 zustand가 인기가 더 많아지고 있고 업데이트와 버전 업데이트도 recoil보다 더 활발하여 zustand를 사용해보기로 했다.
결론적으로는 매우 쉬움 따봉 100개 드립니다.
보일러플레이트가 거의 없고, redux devtools를 사용할 수 있다.
1. 설치
yarn add zustand
2. store생성
// store.js
import create from 'zustand' // create로 zustand를 불러옵니다.
const useStore = create(set => ({
bears: 0,
increasePopulation: () => set(state => ({ bears: state.bears + 1 })),
removeAllBears: () => set({ bears: 0 })
}))
export default useStore
bears가 초깃값.
그 밑에 함수들이 state 중에 bears를 변경시키는 함수이다.
그러나
여기서 내가 궁금했던 점.
이렇게 간단한 플젝을 실제 서비스에서 쓰진 않을 것 아닌가?
나는 여러개의 리듀서가 필요하단 말이다!
실험해본 결과 이 스토어를 여러개 만들면 된다.
아래와 같이..
import create from "zustand";
import { devtools } from "zustand/middleware";
import { persist } from "zustand/middleware";
const useDogStore = create(
devtools((set) => ({
title: "hello",
}))
);
export default useDogStore;
import create from "zustand";
const useBearStore = create((set) => ({
bears: [],
increasePopulation: () => set((state) => ({ bears: state.bears + 1 })),
removeAllBears: () => set({ bears: 0 }),
addBears: (todo) =>
set((state) => ({ bears: [...state.bears, { id: 2, title: todo }] })),
}));
export default useBearStore;
3. 컴포넌트에서 사용
const { bears, increasePopulation, removeAllBears, addBears } = useBearStore((state) => state);
const { title } = useDogStore((state) => state);
이렇게 불러온다.
import React, { useRef } from "react";
import useBearStore from "../../../../zustand/store/useBearStore";
import useDogStore from "../../../../zustand/store/useDogStore";
const Test = () => {
//3뎁스 메뉴 - 페이지(하위 없
const { bears, increasePopulation, removeAllBears, addBears } = useBearStore(
(state) => state
);
const { title } = useDogStore((state) => state);
const todoRef = useRef();
const onAddTodo = () => {
addBears(todoRef.current.value);
};
return (
<div>
<h1>{title}around here ...</h1>
<input ref={todoRef}></input>
<button onClick={onAddTodo}>등록하기</button>
{bears.map((p) => {
return <div key={p.title}>{p.title}</div>;
})}
<button onClick={increasePopulation}>one up</button>
<button onClick={removeAllBears}>remove all</button>
</div>
);
};
export default Test;
이런식으로 사용
4. devtools연결
create바로 뒤에 devtools 적으면 됨
import create from "zustand";
import { devtools } from "zustand/middleware";
const useDogStore = create(
devtools((set) => ({
title: "hello",
}))
);
export default useDogStore;
개발자도구에서 redux를 열어보면 이렇게 상태를 확인할 수 있다.
5. persist사용
상태관리들은 새로고침하면 사라진다는 사실
그래서 계속 유지해야하는 상태들은 persist로 지정해준다.
그렇다면 devtools와 함께 사용해보자
import create from "zustand";
import { devtools } from "zustand/middleware";
import { persist } from "zustand/middleware";
const useBearStore = create(
devtools(
persist(
(set) => ({
bears: [],
increasePopulation: () => set((state) => ({ bears: state.bears + 1 })),
removeAllBears: () => set({ bears: 0 }),
addBears: (todo) =>
set((state) => ({ bears: [...state.bears, { id: 2, title: todo }] })),
}),
{ name: "user-StoreName" }
)
)
);
export default useBearStore;
name에는 localstorage에 어떤 이름으로 저장되고 싶은지 적는다.
개발자도구에 application으로 가서 localstorage를 열어보면 이렇게 적혀있을 것이다.
리코일보다도 더 쉽다니 정말 쉽다.
selector과 subscribe등 기능이 더 있지만 차차 개발하면서 써보는 것으로 하겠다.
리액트를 처음 배우던 1년 반 전부터 지금까지 redux, react-query, recoil, redux-toolkit, jotai, zustand. ... . . .
계속 새로운 상태관리 라이브러리들이 대두되고 (새로 만들어진건 아니겠지만 내가 알게됨)
점점 더 쉬워진다. 이제 리액트가 배우기 어렵다는 것은 옛말이 된 것 같다.
더 자세한 설명은 공식문서 참고.
https://github.com/pmndrs/zustand
'WEB > REACT' 카테고리의 다른 글
[React] input file로 이미지 받고 미리보기 구현하기 (multiple) (0) | 2023.09.01 |
---|---|
[React] react-query (0) | 2023.03.22 |
[React] react router v6 중첩 라우팅, 리다이렉트, 404 페이지 (0) | 2022.12.09 |
react soket 채팅 (0) | 2022.04.08 |
[React] image carousel (0) | 2022.03.20 |