Zustand
zustand-demo.pmnd.rs
Zustand란
Zustand는 React용 여러 상태 관리 라이브러리 중 하나입니다.
Redux vs Zustand
- Provider 미사용 및 코드 간결화
Zustand
import { create } from 'zustand'
type State = {
count: number
}
type Actions = {
increment: (qty: number) => void
decrement: (qty: number) => void
}
const useCountStore = create<State & Actions>((set) => ({
count: 0,
increment: (qty: number) => set((state) => ({ count: state.count + qty })),
decrement: (qty: number) => set((state) => ({ count: state.count - qty })),
}))
import { create } from 'zustand'
type State = {
count: number
}
type Actions = {
increment: (qty: number) => void
decrement: (qty: number) => void
}
type Action = {
type: keyof Actions
qty: number
}
const countReducer = (state: State, action: Action) => {
switch (action.type) {
case 'increment':
return { count: state.count + action.qty }
case 'decrement':
return { count: state.count - action.qty }
default:
return state
}
}
const useCountStore = create<State & Actions>((set) => ({
count: 0,
dispatch: (action: Action) => set((state) => countReducer(state, action)),
}))
const Page = () => {
const count = useCountStore((state) => state.count)
const increment = useCountStore((state) => state.increment)
return (
<div>
<p>{count}</p>
<button onClick={() => increment(1)}>+</button>
</div>
)
}
Redux
import { createStore } from 'redux'
import { useSelector, useDispatch } from 'react-redux'
type State = {
count: number
}
type Action = {
type: 'increment' | 'decrement'
qty: number
}
const countReducer = (state: State, action: Action) => {
switch (action.type) {
case 'increment':
return { count: state.count + action.qty }
case 'decrement':
return { count: state.count - action.qty }
default:
return state
}
}
const countStore = createStore(countReducer)
import { createSlice, configureStore } from '@reduxjs/toolkit'
const countSlice = createSlice({
name: 'count',
initialState: { value: 0 },
reducers: {
incremented: (state, qty: number) => {
// Redux Toolkit does not mutate the state, it uses the Immer library
// behind scenes, allowing us to have something called "draft state".
state.value += qty
},
decremented: (state, qty: number) => {
state.value -= qty
},
},
})
const countStore = configureStore({ reducer: countSlice.reducer })
import { Provider } from 'react-redux'
import { countStore } from './store'
const App = () => (
...
<Provider store={countStore}>
<MyComponent />
</Provider>
)
const Page = () => {
const count = useAppSelector((state) => state.count.value)
const dispatch = useAppDispatch()
return (
<div>
<p>{count}</p>
<button onClick={() => dispatch(incremented(1))}>+</button>
</div>
)
}
Redux는 앱이 컨텍스트 제공자로 래핑되어야 하지만, Zustand는 그렇지 않습니다.
그리고 한 눈에 보기에도 더욱 간결한 코드로 인해 사용이 편해집니다.
- 렌더링 최적화 (Redux 대비)
항목 | Zustand | Redux |
리렌더링 단위 | useStore(state => state.xxx) 단위 (세밀) | useSelector(state => ...) 단위 (얕은 비교) |
잘못 쓰면? | 적게 발생 (부분 구독 강제됨) | 전체 리렌더 발생 가능 (전체 state 구독하면) |
구조상 유리함 | 함수 단위 구독으로 명확함 | 객체 구독 시 실수 여지 있음 |
- zustand npm download수가 더 많다
npm-stat: download statistics for NPM packages
Download statistics To keep this site running and ad-free, I would appreciate a donation. All data comes directly from npm. The charts of this service are powered by Highcharts JS which is provided under a CC BY-NC 3.0 licence. npm-stat.com is not affiliat
npm-stat.com
여담으로 공식 내용은 아니지만 Redux Toolkit은 RTK가 있기 때문에 React Query보다는 RTK가 적합하고 Zustand는 딱 상태관리만 해주기 때문에 React Query에 어울린다는 말이 있네요
출처
'[State Management]' 카테고리의 다른 글
[Redux Toolkit] 리덕스 툴킷 설치 및 사용법 (0) | 2024.01.27 |
---|