React中状态对象添加至另一状态后原有对象被意外修改的问题
问题原因与解决方法
你的问题核心是没遵循React状态的不可变性原则,对象、数组这类引用类型,直接修改原状态或复用引用会引发两个问题:一是React检测不到状态变化,无法触发重渲染;二是共享的引用会让之前存入数组的对象被意外修改。
具体错误点:
修改状态
a时直接篡改原对象Object.assign(a, { hello: event.target.value })会直接修改原状态对象a,而非创建新对象。这导致a的引用始终没变,后续存入数组b的都是同一个对象引用,修改输入框时会同步改变数组里所有指向该引用的元素。更新数组
b时复用原数组引用const newB = b只是复制了数组的引用,newB.push(a)修改的还是原状态数组,setB(newB)因为引用未变,React不会识别为状态更新;再加上数组里的元素都是a的同一个引用,自然会跟着a的修改而变化。
修正后的代码:
export default function () { const [a, setA] = useState({ hello: "world" }); const [b, setB] = useState([]); const Submit = () => { // 创建新数组,添加当前a的对象 setB([...b, a]); console.log(b); }; return ( <> <input type="text" onChange={(event) => { // 创建新对象,替换原状态a setA({ ...a, hello: event.target.value }); }} /> <button onClick={Submit}>Submit</button> </> ); }
关键修改说明:
- 更新
a时使用对象展开运算符{ ...a, hello: event.target.value },创建一个包含原对象所有属性、同时覆盖hello的新对象,保证每次修改都是新的引用。 - 更新
b时使用数组展开运算符[...b, a],创建原数组的副本并添加新元素,既避免修改原数组,又能让React检测到状态变化。
如果要处理嵌套对象,同样要保证每一层都是新的引用,比如嵌套对象修改时要逐层展开创建新对象。
内容的提问来源于stack exchange,提问作者Wijze
相关产品推荐
相关产品推荐

