我正在使用 Redux 订阅商店并更新组件。
这是一个没有 Redux 的简化示例。它使用模型商店进行订阅和分发。
请按照片段下方的步骤重现问题。
编辑:请跳到更新下的第二个演示片段,以获得更简洁和更接近现实生活的场景。问题不在于 Redux。这是关于 React 的 setState 函数标识在某些情况下导致重新渲染,即使状态没有改变。
编辑 2 :在“更新 2 ”下添加了更简洁的演示。
const {useState, useEffect} = React;
let counter = 0;
const createStore = () => {
const listeners = [];
const subscribe = (fn) => {
listeners.push(fn);
return () => {
listeners.splice(listeners.indexOf(fn), 1);
};
}
const dispatch = () => {
listeners.forEach(fn => fn());
};
return {dispatch, subscribe};
};
const store = createStore();
function Test() {
const [yes, setYes] = useState('yes');
useEffect(() => {
return store.subscribe(() => {
setYes('yes');
});
}, []);
console.log(`Rendered ${++counter}`);
return (
<div>
<h1>{yes}</h1>
<button onClick={() => {
setYes(yes === 'yes' ? 'no' : 'yes');
}}>Toggle</button>
<button onClick={() => {
store.dispatch();
}}>Set to Yes</button>
</div>
);
}
ReactDOM.render(<Test />, document.getElementById('root'));
<div id="root"></div>
<script src="https://unpkg.com/react/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom/umd/react-dom.development.js"></script>
✅ 单击“设置为是”。由于 的值yes
已经是“yes”,状态没有改变,因此组件不会重新渲染。
✅ 点击“切换”。yes
设置为“否”。状态已经改变,所以组件被重新渲染。
✅ 单击“设置为是”。yes
设置为“是”。状态再次改变,所以组件被重新渲染。
⛔ 再次单击“设置为是”。状态没有改变,但组件仍然重新渲染。
✅ 后续点击“设置为是”不会按预期导致重新渲染。
在第 4 步,不应重新渲染组件,因为状态未更改。
白衣非少年
斯蒂芬大帝
相关分类