如何在 React 中进行状态管理?使用 Zustand!
目录
计数器
import { create } from 'zustand'
const useStore = create(set => ({
count: 1,
inc: () => set(state => ({ count: state.count + 1 })),
}))
function Controls() {
const inc = useStore(state => state.inc)
return <button onClick={inc}>one up</button>
}
function Counter() {
const count = useStore(state => state.count)
return <h1>{count}</h1>
}
用法
创建状态 state 操作 action
Basic typescript usage doesn’t require anything special except for writing create<State>()(...)
instead of create(...)
…
import { create } from 'zustand'
interface BearState {
bears: number
increase: (by: number) => void
}
const useBearStore = create<BearState>()((set) => ({
bears: 0,
increase: (by) => set((state) => ({ bears: state.bears + by })),
}))
const useFishStore = create((set) => ({
salmon: 1,
tuna: 2,
deleteEverything: () => set({}, true), // clears the entire store, actions included
deleteTuna: () => set((state) => omit(state, ['tuna']), true),
}))
const useSoundStore = create((set, get) => ({
sound: "grunt",
action: () => {
const sound = get().sound // you still have access to state outside of it through get
// ...
}
})
export default useBearStore
在 react 之外使用呢?
import { createStore } from 'zustand/vanilla'
const store = createStore(() => ({ ... }))
const { getState, setState, subscribe } = store
export default store
import { useStore } from 'zustand'
import { vanillaStore } from './vanillaStore'
const useBoundStore = (selector) => useStore(vanillaStore, selector)
获取状态
// It will cause the component to update on every state change!
const state = useBearStore()
// It detects changes with strict-equality (old === new) by default, this is efficient for atomic state picks.
const bears = useBearStore((state) => state.bears)
// Object pick, re-renders the component when either state.nuts or state.honey change
const { nuts, honey } = useBearStore(
(state) => ({ nuts: state.nuts, honey: state.honey }),
shallow
)
// Array pick, re-renders the component when either state.nuts or state.honey change
const [nuts, honey] = useBearStore(
(state) => [state.nuts, state.honey],
shallow
)
// Mapped picks, re-renders the component when state.treats changes in order, count or keys
const treats = useBearStore((state) => Object.keys(state.treats), shallow)
// You may provide any custom equality function
const treats = useBearStore(
(state) => state.treats,
(oldTreats, newTreats) => compare(oldTreats, newTreats)
)
const increase = useBearStore((state) => state.increase)
在组件之外如何使用?
const useDogStore = create(() => ({ paw: true, snout: true, fur: true }))
// Getting non-reactive fresh state
const paw = useDogStore.getState().paw
// Listening to all changes, fires synchronously on every change
const unsub1 = useDogStore.subscribe(console.log)
// Updating state, will trigger listeners
useDogStore.setState({ paw: false })
// Unsubscribe listeners
unsub1()
// You can of course use the hook as you always would
const Component = () => {
const paw = useDogStore((state) => state.paw)
...