使用setState无法更新Zustand状态且需避免Comp2组件重渲染
问题根因
你遇到的问题本质是两个独立原因导致的:
- 你以为
useStoreOnHover.setState或者单独取onComp1Set没生效,是因为你在Comp1中用useStoreOnHover.getState().onComp1取状态,这个API是静态读取当前store的快照,不会订阅状态变化,所以store里的onComp1实际已经更新了,但Comp1不会触发重渲染,界面自然不会更新,不是set操作没生效。 - 你担心取状态会导致其他组件重渲染,是误解了zustand selector的工作逻辑:只有组件通过selector订阅的状态值发生变化时,才会触发当前组件重渲染,其他未订阅的状态变化不会影响当前组件。你之前用全量解构
const { onComp1Set } = useStoreOnHover()会触发多余重渲染,是因为这种写法等于订阅了整个store的所有状态变化,只要store任意值更新就会触发当前组件重渲染。
正确实现方案
你只需要修改Comp1的取值逻辑即可,完全满足「悬浮更新onComp1、仅Comp1重渲染、Comp2无感知」的要求:
const Comp1 = () => { // 仅订阅onComp1的变化,只有该值变动时才会触发Comp1重渲染 const onComp1 = useStoreOnHover((s) => s.onComp1); // 仅取onComp1Set方法,store中的action引用永远稳定,不会触发任何重渲染 const onComp1Set = useStoreOnHover((s) => s.onComp1Set); console.log("Comp 1", onComp1); return ( <div onMouseEnter={() => { onComp1Set(true); }} > Comp 1 {onComp1 ? "True" : "False"} </div> ); };
效果验证
- 悬浮Comp1时,控制台仅会打印
Comp 1 true,Comp2的log仅在初始化时打印一次,不会重新触发 - 不需要直接调用
useStoreOnHover.setState,也不需要全量解构store,不会引发多余的重渲染
内容的提问来源于stack exchange,提问作者Marius
相关产品推荐
相关产品推荐

