Zustand 상태 관리

Zustand 상태관리 라이브러리를 찍먹해봤다. 작년부터 스멀스멀 인기가 올라가더니 상태관리 라이브러리 하면 Redux, Recoil, Zustand 세 개의 대명사가 떠오르게 됐다. Recoil도 안써봤지만 😎
공식 문서 소개글은 이렇다. 단순화된 플럭스 원리를 사용하는 작고 빠르고 확장성있는 상태 관리 솔루션으로 훅 기반 편안한 API 제공.
독단적이지 않다고 강조하는데, 말 잘 들을 것 같은 위 곰돌이(?) 가 증명해주는 것 같았다.
Zustand는 Legend! 👍
Redux 또는 RTK, useContext 로 전역 상태 관리를 해봤다면 느꼈을 텐데, 이렇게 간단히 상태 관리를 구현해도 될 정도인가?라는 의문이 들었다. 그리고 Zustand를 사용하니 선언형 방식의 프로그래밍을 몸소 실천하고 있는 기분이 든다.
장점
- 특정 라이브러리에 엮이지 않고 리액트와 함께 사용 가능
- 상태를 정의하고 사용 방법이 단순
- 상태 변경 시 불필요한 리렌더링 방지 제어 가능
- 핵심 로직의 코드 줄 수가 약 42줄😯
Zustand Guide
📌 설치
yarn add zustand📌 스토어 생성(feat. TypeScript)
// /src/zustand/store.ts
import { create } from 'zustand'
import { devtools, persist } from 'zustand/middleware'
interface BearState {
bears: number
increase: (by: number) => void
}
export const useBearStore = create<BearState>()(
devtools(
persist(
(set) => ({
bears: 0,
increase: (by) => set((state) => ({ bears: state.bears + by })),
}),
{
name: 'bear-storage', // persist key
}
)
)
)bears 라는 곰의 카운트와 증가시키는 increase 함수가 예제로 나와있다. 미들웨어 persist 를 기본 제공한다.
📌 사용하기
도대체 뭘 했다고 벌써 사용을 한단 말인가..? Provider로 감싸주고 이것저것 더 만들어야 하지 않나 싶었는데 공식 문서에 that’s it! 이란다.
import { useBearStore } from './zustand/store'
const App = () => {
const bears = useBearStore((state) => state.bears)
const upBear = useBearStore((state) => state.increase)
return (
<div className="App">
<center>
<a href="https://vitejs.dev" target="_blank" rel="noreferrer">
<img src="/vite.svg" className="logo" alt="Vite logo" />
</a>
</center>
<h1>Vite + React</h1>
<div className="card">
<center>
<h2>count is {bears}</h2>
</center>
<center>
<button
type="button"
onClick={() => {
upBear(100)
}}
>
증가
</button>
</center>
</div>
</div>
)
}
export default App예제로 코드 작성을 해보고 지금하는 프로젝트에서 리덕스를 지워버렸다.
🚀 Transient updates
주스탠드는 리덕스에 없는 특별한 기능을 제공하는데, 자주 업데이트되는 상태에 컴포넌트 리렌더링을 방지하는 기능이다. 이 점은 성능에 큰 영향을 줄 수 있으니 유용하게 사용하자!
import { useRef, useEffect } from 'react'
import { useBearStore } from './zustand/store'
const App = () => {
const bearsRef = useRef(useBearStore.getState().bears)
const upBear = useBearStore((state) => state.increase)
const clear = useBearStore((state) => state.clear)
useEffect(() => {
useBearStore.subscribe((state) => {
bearsRef.current = state.bears
})
}, [])
...useRef, useEffect훅으로 선언과 할당해주고 bearsRef.current 로 접근
GitHub - macjjuni/react18-ts-boilerplate: feat. SWC
📌 리액트 컴포넌트 밖에서 사용하기
import { useBearStore } from './zustand/store'
const { getState } = useBearStore
const clickEvent = () => {
getState().increase()
}So Easy~❤️