本文最后更新于247 天前,其中的信息可能已经过时,如有错误请发送邮件到1986413837@qq.com
主要内容
基本使用
异步和immer中间件
简化状态获取 useShallow
Redux DevTools 查看状态
persist中间件进行持久化
使用subscribe订阅
使用setState和getState规整代码
代码示例
/src/store/appleStore.ts
import { create } from "zustand";
import { createJSONStorage, devtools, persist, subscribeWithSelector } from "zustand/middleware";
import { immer } from "zustand/middleware/immer";
//immer中间件 简化state操作
// subscribeWithSelector
interface AppleStateType {
price: number
count: number,
color: string,
// increment: () => void,
// decrement: () => void,
// getTotal: () => number,
// doubleCount: () => Promise<undefined> //async函数返回Promise 没有return 任何值 相当于return undefined
}
// 工具函数 get() set()
const useAppleStore = create<AppleStateType>()(immer(devtools(
subscribeWithSelector(
persist(() => ({
price: 7.0,
count: 10,
color: 'red',
//partialize: (state) => ({ price: state.price }) 只对价格进行持久化
// partialize: (state) => Object.fromEntries(
// Object.entries(state).filter(([key, _]) => !['price'].includes(key))
// ) 除了价格都持久化
}), {
name: 'myAppleStore',
partialize: (state) => Object.fromEntries(
Object.entries(state).filter(([key, _]) => !['price'].includes(key))
),
storage: createJSONStorage(() => sessionStorage) //指定存储位置
})
),
{ enabled: true, name: "Apple Store" })))
export default useAppleStore
export const increment = () => {
useAppleStore.setState((state) => { state.count += 1 })
}
export const decrement = () => {
useAppleStore.setState((state) => { state.count -= 1 })
}
export const getTotal = () => {
return useAppleStore.getState().price * useAppleStore.getState().count
}
export const doubleCount = async () => {
const rate = await Promise.resolve(2)
useAppleStore.setState((state) => { state.count *= rate })
}
/src/App.tsx
import { shallow, useShallow } from "zustand/shallow"
import useAppleStore, { decrement, doubleCount, getTotal, increment } from "./store/appleStore"
import { useEffect, useState } from "react"
const Child1 = () => {
const price = useAppleStore(state => state.price)
const count = useAppleStore(state => state.count)
//使用setState修改状态
const myLocalAction = () => {
useAppleStore.setState((state) => { state.count += 3 })
}
//使用getState获取状态
return (
<>
<h1>单价:{price}</h1>
<h1>数量:{count}</h1>
<h1>金额:{getTotal()}</h1>
<button onClick={increment}> +1 </button>
<button onClick={decrement}> -1 </button>
<button onClick={doubleCount}> x2 </button>
<button onClick={myLocalAction}>组件一 独有+3动作 </button>
<div>使用getState获取状态: {useAppleStore.getState().count}</div>
</>
)
}
const Child2 = () => {
//解构获取 默认获取所有状态
//Child1中状态改变 Child2依旧会重新渲染
// const { price, color } = userAppleStore()
const [text, setText] = useState('太少')
//useShallow
//useShallow用于优化 zustand 状态选择,避免不必要的渲染
//它会对新旧状态进行浅比较,只有真正变化时才触发更新
const { price, color } = useAppleStore(useShallow(state => ({
price: state.price,
color: state.color,
})))
//希望只订阅一次
//状态改变之后 执行了订阅的代码
useEffect(() => {
const cancelSub = useAppleStore.subscribe(
state => state.count, //监听指定的状态
(count, preCount) => {
if (count > 7 && preCount <= 7 || count === preCount && count > 7) {
setText('已经很多了')
} else if (count <= 7 && preCount > 7 || count === preCount && count <= 7) {
setText('太少')
}
},
{
equalityFn: shallow,
fireImmediately: true
},
)
return cancelSub
}, [])
console.log('---Child2---')
return (
<>
<h1>单价:{price}</h1>
<h1>颜色:{color}</h1>
<h1>{text}</h1>
{/* 例如count为0时 每加一次 Child2都会重新渲染 我想要他改变到>7再重新渲染 */}
{/* 使用订阅 */}
</>
)
}
function App() {
return (
<>
<Child1>
</Child1>
<hr />
<Child2>
</Child2>
</>)
}
export default App