在React开发中遇到了一个问题:

需求是在一个选择组件中选择数据mydata数组,确定后将mydata数组返回到父组件,再次打开该选择组件时,从父组件获取之前选择的数据mydata并显示为已选择。

    /* 打开选择组件 */
showModal = () => {
this.setState({
comVisible: true
});
const { mydata } = this.props;
this.setState({
mydata: mydata
});
console.log(this.state.mydata);
this.onChange();
} /* 确定-将data返回父组件 */
handleOk = () => {
if (this.state.mydata.length > 0) {
this.setState({
comVisible: false
});
// 返回父组件data
this.props.getMyData({
mydata: this.state.mydata,
...
});
} else {
message.error("data is null");
}
} /* 取消-不对data做操作 */
handleCancel = () => {
this.setState({
comVisible: false
});
}
/* 选择data */
onChange = (mydata) => {
let mydata = this.state.mydata;
Object.keys(otherdata).forEach((title) => {
...
// 对mydata做一些改变
});
this.setState({
mydata
});
}

大概流程如下:

按照逻辑,在选择组件中选择mydata,触发onChange事件,将此时改变的mydata设置为state.mydata,点击确定后触发handleOk函数,将state.mydata传给父组件。但若点击取消,则触发handleCancel,不做任何操作。

那么问题来了,我点击了取消,再次打开选择组件,从父组件取mydata的值,取到的是点击取消之前选择的mydata值。按理说点击了取消不做操作,该值是不会传给父组件的,但是为什么从父组件会取到改变后的值呢?

经过一系列尝试后发现,问题的原因在于数组的表现形式就是内存中的一段连续的内存地址,数组名称其实就是连续内存地址的首地址。onChange中对mydatastate.mydata的改变会直接改变该数组所指向的地址中的数据,而父组件中的mydata也是指向该数组的,所以一旦state.mydata发生改变,即使不将改变后的mydata传给父组件,父组件的mydata也会改变。

修改:给父组件传值时使用中间变量,并且数组赋值时,使用先结构再赋值的方式生成新的数组。

    /* 打开选择组件 */
showModal = () => {
this.setState({
comVisible: true
});
const { mydata } = this.props;
this.setState({
mydata: mydata
});
this.onChange();
} /* 确定-将data返回父组件 */
handleOk = () => {
if (this.state.mydata.length > 0) {
// 返回父组件data,改变后的中间变量
this.props.getMyData({
mydata: this.state.tempdata,
...
});
} else {
message.error("data is null");
}
} /* 取消-不对data做操作 */
handleCancel = () => {
...
}
/* 选择data */
onChange = (mydata) => {
// 改变赋值方式
let mydata = [];
mydata.push(...this.state.mydata);
Object.keys(otherdata).forEach((title) => {
...
// 对mydata做一些改变
});
// 使用中间变量,不直接修改state.mydata
this.setState({
tempdata: mydata
});
}

总结:

在JS中,

数组和对象是地址型变量

数组和对象是地址型变量

数组和对象是地址型变量


基础知识一定时刻记在脑子里。。。

在React开发中遇到的问题——数组引用赋值的更多相关文章

  1. 聊一聊,React开发中应该规避的点

    原文永久链接: https://github.com/AttemptWeb..... 下面说到的React开发中注意的问题,部分是自己遇到过的点,部分是收集的,也算是React代码优化部分,这次做一个 ...

  2. React开发中react-route-dom使用BrowserRouter部署到服务器上刷新时报404的问题

    React项目部署中遇到的问题 react开发中react-route使用BrowserRoute路径在iis服务器上刷新时报404的问题 解决:在发布的项目根目录添加web.config配置文件 在 ...

  3. react 开发中的问题简记

    1.什么时候用props 什么时候用state ? 不能使用props:当页面组件存在URL跳转问题时候,原因:若单独刷新,他会报错,拿不到前面的数据: 使用props场景:当组件为页面组件的一部分即 ...

  4. React 开发中面临的九个重要抉择

    抉择系列:在技术开发的过程中我们会面临着各种各样的抉择,我们在不同情境下该如何选择恰当的技术,这是本系列文章想要解决的问题. 在 React 开发的过程中我们常常会遇到一些抉择,下面我将选取其中一些个 ...

  5. react开发中如何使用require.ensure加载es6风格的组件

    其实用的babel,在浏览器端就应该可以加载,之前少了个default: require.ensure([],(require) => { let A = require('./a.js').d ...

  6. react开发中的小细节

    目前开始使用react余遇到的问题还不是很多,但还是希望总结一下. react中的属性prop: 在react中组件的父子组件的通信是基于prop的,当然对于底层的东西不是特别了解,但可以说一说它的基 ...

  7. c语言结构体中的一个char数组怎么赋值?

    目录 前景提示 这里的结构体处理的步骤 一.char数组类型的处理 二.char数组指针类型的处理 三.全部代码 1. char数组 2. char数组指针 结语 前景提示 定义一个结构体,结构体中有 ...

  8. Mybatis开发中前端控制器注解@Controller 引用的类错误

    import org.springframework.web.portlet.ModelAndView; 错误 import org.springframework.web.servlet.Model ...

  9. 21个React开发神器

    摘要: React开发神器. 原文:22 Miraculous Tools for React Developers in 2019 译者:前端小智 下列工具中的重要性与排序无关. 1.Webpack ...

随机推荐

  1. c#编程:给定一个正整数求出是几位数并逆序输出

    <span style="color:#FF0000;">第一步:把输入的数字转为字符串n.ToString() 第二步:求出字符串的长度即为正整数的位数 第三步:从后 ...

  2. iOS开发之Quartz2D 五:UIKIT 绘图演练,画文字,画图片

    #import "DrawView.h" @implementation DrawView -(void)awakeFromNib { // //画图片 // UIImage *i ...

  3. Java并发包探秘 (一) ConcurrentLinkedQueue

    本文是Java并发包探秘的第一篇,旨在介绍一下Java并发容器中用的一些思路和技巧,帮助大家更好的理解Java并发容器,让我们更好的使用并发容器打造更高效的程序.本人能力有限,错误难免.希望及时指出. ...

  4. Android自己定义控件2-简单的写字板控件

    概述 上一篇文章我们对自己定义控件进行了一个大体的知识介绍. 今天就来学习自己定义一个简单的写字板控件. 先来看看效果图 就是简单的依据手指写下的轨迹去画出内容 实现 在上一篇文章里提到了androi ...

  5. GCD网络多线程---同步运行,异步运行,串行队列,并行队列

    总结:同步(无论是串行还是并行)----不又一次开辟子线程 异步(无论是串行还是并行)----开辟子线程 GCD: dispatch queue 主线程的main queue 并行队列 global ...

  6. 【hdu 2594】Simpsons’ Hidden Talents

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s) ...

  7. Guava中TreeRangeMap基本使用

    RangeMap跟一般的Map一样.存储键值对,依照键来取值.不同于Map的是键的类型必须是Range,也既是一个区间.RangeMap在Guava中的定义是一个接口: public interfac ...

  8. Java序列化机制中的类版本号问题

    原文地址:http://yanwushu.sinaapp.com/java_serialversionuid/ 内容简单介绍 某些实现了serializable接口的java类中会看到名称为seria ...

  9. [Angular] @ViewChild and template #refs to get Element Ref

    We can use @ViewChild with component: @ViewChild(AuthMessageComponent) message: AuthMessageComponent ...

  10. 移动CMPP3.0接口

    前段时间准备上线期,同事接了个联调CMPP3.0短信接口的任务,但是一直不成功,抽时间给解决了一下,记录下其中几个要点: 1.短信网关厂家需要提供参数: #网关IP地址 ismgIp=1.1.1.1# ...