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

React Native中使用本地变量初始化状态后,更新状态时本地变量为何同步被修改?

为什么修改React Native的state会同时改变初始的initData变量?

这是JavaScript里引用类型赋值的经典坑,我来给你掰扯清楚原因和解决办法:

问题根源

你代码里的route.params.data如果是对象、数组这类引用类型,那么let initData = route.params.data;这行代码并没有复制数据本身,只是把initData指向了和route.params.data同一个内存地址的引用。

当你修改state的时候(比如直接修改state的某个属性再调用setState),其实是在操作共享内存里的那个对象,而initData因为指向同一个内存地址,自然也会跟着变化。

用你的代码场景举个例子:

// 假设route.params.data是一个对象
route.params.data = { name: 'old name' };
let initData = route.params.data;
const [state, setState] = React.useState(initData);

// 修改state的属性
setState(prev => {
  prev.name = 'new name';
  return prev;
});

console.log(initData.name); // 会输出 'new name',因为指向同一个对象

解决办法

核心思路是创建原数据的独立副本,让initData和state指向不同的内存地址,根据数据结构复杂度,有几种方案:

1. 简单对象/数组:用扩展运算符浅拷贝

如果你的data是没有嵌套结构的简单对象或数组,直接用扩展运算符生成新副本:

// 简单对象
let initData = {...route.params.data};
// 数组
let initData = [...route.params.data];

const [state, setState] = React.useState(initData);

2. 嵌套对象/数组:深拷贝

如果数据有多层嵌套(比如对象里包含子对象/数组),浅拷贝就不够用了,推荐两种方案:

方案A:JSON序列化(适合无特殊类型的数据)

let initData = JSON.parse(JSON.stringify(route.params.data));
const [state, setState] = React.useState(initData);

注意:如果数据里包含函数、日期对象、正则表达式这类JSON无法序列化的类型,这个方法会丢失这些数据。

方案B:使用lodash的cloneDeep(复杂场景首选)

先安装依赖:

npm install lodash.clonedeep
# 或者 yarn add lodash.clonedeep

然后使用:

import cloneDeep from 'lodash.clonedeep';

let initData = cloneDeep(route.params.data);
const [state, setState] = React.useState(initData);

这个方法能完美处理所有类型的引用数据,包括嵌套结构、函数、日期等。

3. 额外提醒:修改state要遵循不可变原则

即使做了拷贝,修改state时也尽量不要直接修改原state对象,而是返回新对象,这符合React的设计理念:

// 正确做法:返回新对象
setState(prevState => ({
  ...prevState,
  name: 'new name' // 只更新需要修改的属性
}));

// 错误做法:直接修改原state对象
// state.name = 'new name';
// setState(state);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 17:59:04