You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:29:45