React.js中state仅首次更新成功后续失效,子组件无法接收最新props
问题原因
你的代码核心问题是在setSelectedFilters的回调函数中直接修改了原有state中的Set实例,属于可变修改原状态的错误操作:
const newSFSet = sf[filter_key]; // 直接引用原state里的Set实例,没有做拷贝 if (newSFSet.has(filter_id)) { newSFSet.delete(filter_id); // 直接修改原state的Set,属于副作用 } else { newSFSet.add(filter_id); // 直接修改原state的Set,属于副作用 }
这种操作在React 18的严格模式下会直接导致状态异常:严格模式为了检测不安全的副作用,会执行两次setState的回调函数。第一次执行回调时已经把原state的Set修改了,第二次执行时拿到的就是被污染的旧state,最终计算出来的新状态不符合预期,就会出现你遇到的“更新后回退、子组件收不到后续更新”的问题。
修复方案
只需要修改一行代码,对原state中的Set先做拷贝再修改即可:
const filterChanged = useCallback((filter_key, filter_id) => { setSelectedFilters((sf) => { // 先拷贝原Set,所有修改都在拷贝后的实例上操作,不污染原state const newSFSet = new Set(sf[filter_key]); if (newSFSet.has(filter_id)) { newSFSet.delete(filter_id); } else { newSFSet.add(filter_id); } const newSF = { ...sf, [filter_key]: newSFSet }; return newSF; }); }, []);
修改后你没有再修改原state的任何内容,所有更新都是不可变操作,严格模式下的两次执行也不会互相干扰,状态更新和子组件props传递都会恢复正常。
内容的提问来源于stack exchange,提问作者Himanshu Naidu
相关产品推荐
相关产品推荐

