为什么使用Zustand这类状态管理库后React组件仍然会重渲染?
问题原因
你当前的写法会导致组件重渲染的核心原因是:Zustand 默认会监听整个 store 的所有状态变更,只要 store 内任意值发生变化,调用了stateButton()的组件就会触发重渲染,和你是否用到了变化的状态字段无关。你当前组件虽然只用到了setBtn方法,但store 内getBtn每次滚动更新时,依旧会触发组件重渲染。
解决方法
只需要在调用store时传入选择器,只订阅你实际需要用到的内容即可,setBtn作为store内置的更新方法引用是固定不变的,不会触发订阅更新:
// 原来的写法,订阅整个store // const { setBtn } = stateButton(); // 修改后的写法,只订阅setBtn方法 const setBtn = stateButton(state => state.setBtn);
修改后的完整App.js代码如下:
import { stateButton } from "./stateButton"; import { Scrollbar } from "react-scrollbars-custom"; export default function App() { // 仅选择需要的setBtn方法 const setBtn = stateButton(state => state.setBtn); console.log("rendering"); return ( <div> <Scrollbar style={{ width: "250px", height: "50px" }} onScroll={() => setBtn(1)} > <div>Test</div> <div>Test</div> <div>Test</div> <div>Test</div> <div>Test</div> <div>Test</div> <div>Test</div> </Scrollbar> </div> ); }
如果需要同时选择多个状态字段,可以配合shallow浅比较避免不必要重渲染:
import shallow from 'zustand/shallow'; // 同时选择多个字段,只有这两个字段值变化时才会触发重渲染 const { getBtn, setBtn } = stateButton(state => ({ getBtn: state.getBtn, setBtn: state.setBtn }), shallow);
内容的提问来源于stack exchange,提问作者Marius
相关产品推荐
相关产品推荐

