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

ReactJS中如何将外部数组复制到state且不修改原数据?

如何在React中复制数组到state且不修改原数据?

你碰到的核心问题是浅拷贝导致的引用共享:扩展运算符[...mydata]只会复制数组的外层结构,但数组里的每个对象依然和原数组中的对象指向同一个内存地址——所以你修改state里对象的属性时,原数组的对象也会被同步修改。

解决思路:实现深拷贝(至少拷贝到对象层级)

我们需要把数组里的每个对象也单独拷贝一份,让state里的对象和原数组完全独立,这里有几种简单的实现方式:


1. 结合map和对象扩展运算符(推荐,适合简单对象)

这种方式可以精准地拷贝每个对象,而且只复制需要的属性,性能也不错:

state = { 
  myNewData: mydata.map(item => ({ ...item })) 
}

2. 使用JSON.parse(JSON.stringify())(适合无特殊类型的数据)

如果你的数据结构里没有函数、日期、正则这类特殊类型,可以用这种快速的深拷贝方式:

state = { 
  myNewData: JSON.parse(JSON.stringify(mydata)) 
}

⚠️ 注意:这种方法会丢失特殊类型的信息,比如日期会变成字符串,函数会被忽略,所以只适合纯JSON结构的数据。

3. 第三方库(比如Lodash的cloneDeep)

如果数据结构复杂,直接用成熟的深拷贝工具更省心:

import cloneDeep from 'lodash/cloneDeep';

// ...
state = { 
  myNewData: cloneDeep(mydata) 
}

还要修正你代码里的其他问题

除了拷贝的问题,你的代码还有几个React语法错误,我一起整理了修正后的完整代码:

import React, { Component } from 'react';
import { mydata } from './external-data.js';

class HumanApp extends Component {
  // 初始化state时完成深拷贝
  state = { 
    myNewData: mydata.map(item => ({ ...item })) 
  }

  componentDidMount() {
    this.changeData();
  }

  // 类方法不要用const定义,这里用箭头函数避免this指向问题
  changeData = () => {
    // 遵循React不可变数据原则:创建新数组,不要直接修改state
    const updatedData = this.state.myNewData.map(item => ({
      ...item,
      name: 'boyka'
    }));

    // 使用setState更新state,在回调里获取最新的state值(因为setState是异步的)
    this.setState({ myNewData: updatedData }, () => {
      console.log("state Data: " + this.state.myNewData[0].name);
      console.log("original Data:" + mydata[0].name);
    });
  }

  render() {
    return (
      <div>
        {/* 这里放你的渲染内容 */}
      </div>
    );
  }
};

export default HumanApp;

关键说明:

  • 不要直接修改this.state里的内容,必须通过setState更新,这是React的核心规则。
  • setState是异步操作,所以如果要获取更新后的state,要在它的回调函数里执行。
  • 原数组的变量名是mydata,注意大小写不要写错(你之前代码里写成了Mydata)。

内容的提问来源于stack exchange,提问作者Ahmed Boutaraa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 15:48:14