主题
状态简化
更新: 9/4/2025字数: 0 字 时长: 0 分钟
回忆一下我们在使用 zustand 时,是这样引入状态的(如下),通过解构的方式引入状态,但是这样引入会引发一个问题,例如 A 组件用到了 user.name 状态,而 B 组件 没有用到 user.age 状态,但是更新 user.age 这个状态的时候,A 组件和 B 组件都会重新渲染,这样就导致了不必要的重渲染,因为 B 组件并没有用到 user.age 这个状态。
tsx
import React from "react";
import useBearStore from "../../../store/zustand";
function ZustandPage() {
// 使用解构赋值
const { user } = useBearStore();
return (
<div>
<div>
<h1>Zustand 解构赋值</h1>
<p>user.name: {user.name}</p>
<button onClick={() => user.setName("张三")}>{user.name}</button> <br></br>
<button onClick={() => user.setAge(18)}>{user.age}</button> <br></br>
</div>
</div>
);
}
export default ZustandPage;状态选择器
所以为了规避这个问题,我们可以使用状态选择器,状态选择器可以让我们只选择我们需要的部分状态,这样就不会引发不必要的重渲染。
ts
const name = useUserStore((state) => state.user.name);
const age = useUserStore((state) => state.user.age);
const setName = useUserStore((state) => state.user.setName);
const setAge = useUserStore((state) => state.user.setAge);
...useShallow
如果一个属性很多,例如 10+ 个,那我们写起来岂不是要疯了,但是你用解构的话他又会造成不必要的重渲染,时候我们就可以使用useShallow来避免这个问题。
useShallow 可以用来优化性能,当我们只需要选择部分状态,而不需要选择全部状态时,useShallow 可以避免不必要的重渲染。
useShallow 只检查顶层对象的引用是否变化,如果顶层对象的引用没有变化(即使其内部属性或子对象发生了变化,但这些变化不影响顶层对象的引用),使用 useShallow 的组件将不会重新渲染
tsx
import { useShallow } from "zustand/react/shallow";
const { user, cart } = useStore(
useShallow((state) => ({
user: state.user,
cart: state.cart
}))
);