React未通过setState修改key致状态异常:多次恢复初始状态失效
解决React货币表格第二次恢复无反应的问题
嘿,我完全懂你遇到的这个困扰——第一次恢复表格正常,第二次点恢复就没动静了,这种情况在React操作引用类型状态时特别常见,核心问题大概率是你不小心把初始数据的引用给污染了!
问题根源分析
你提到状态里有shownData(当前展示数据)和initialData(初始数据),如果你的代码是这么写的:
- 从API拿到数据后,直接把
initialData和shownData都设为同一个数组/对象(比如setInitialData(apiData); setShownData(apiData);) - 恢复操作时直接赋值:
setShownData(initialData)
那问题就来了:数组和对象是引用类型,这时候initialData和shownData指向的是内存里的同一个数据。当你删除或者添加数据时,其实是在修改这个共享的数据,第一次恢复时看起来正常,但此时initialData已经被改成和shownData删除后的状态一样了!第二次再点恢复,自然没变化——因为两者已经完全相同了。
具体解决方案
1. 初始化时就做好数据隔离
从API获取数据后,要给initialData存一个独立的拷贝,而不是直接用API返回的原数据引用:
useEffect(() => { const fetchCurrencyData = async () => { const res = await fetch('你的货币API地址'); const rawData = await res.json(); // 用扩展运算符做浅拷贝(如果是一维数组) setInitialData([...rawData]); setShownData([...rawData]); // 如果是嵌套对象,要用深拷贝,比如: // setInitialData(JSON.parse(JSON.stringify(rawData))); }; fetchCurrencyData(); }, []);
2. 恢复操作时使用初始数据的拷贝
恢复按钮的点击事件里,不要直接赋值initialData,而是给shownData传一个initialData的拷贝,确保每次恢复都是用最开始的干净数据:
const handleReset = () => { // 一维数组用扩展运算符即可 setShownData([...initialData]); // 嵌套数据用深拷贝: // setShownData(JSON.parse(JSON.stringify(initialData))); };
3. 操作数据时只修改shownData
不管是删除还是添加货币,都只对shownData进行修改,绝对不要碰initialData,让它一直保持从API获取到的初始状态:
// 删除示例 const handleDelete = (currencyId) => { setShownData(prevData => prevData.filter(item => item.id !== currencyId)); }; // 添加示例 const handleAdd = (newCurrency) => { setShownData(prevData => [...prevData, newCurrency]); };
额外提醒
如果你的货币数据里有嵌套对象(比如每个货币项包含汇率历史这种子对象),浅拷贝(扩展运算符、slice())就不够用了,这时候必须用深拷贝来确保数据完全独立。除了JSON.parse(JSON.stringify()),你也可以自己写深拷贝函数,或者用成熟的工具库(比如lodash的cloneDeep)。
内容的提问来源于stack exchange,提问作者nikit
相关产品推荐
相关产品推荐

