在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. JavaScript对象的创建

    原文 简书原文:https://www.jianshu.com/p/6cb1e7b7e379 大纲 前言 1.简单方式创建对象的方法 2.工厂模式创建对象 3.构造函数模式创建对象 4.原型模式创建对 ...

  2. term- xshell VS securecrt

    Xshell使用技巧总结 https://www.cnblogs.com/zhangwuji/p/7155575.html SecureCRT与Xshell简单对比 http://ju.outofme ...

  3. 如何在 BitNami 中创建多个 WEB 应用?(转)

    本文最后更新于2015年7月14日,已超过半年没有更新,如果内容失效,请反馈,谢谢! 如您所知,BitNami 为诸多开源 WEB 应用提供集成环境的一键安装解决方案,像著名的开源 WEB 程序 Wo ...

  4. 使用ToolRunner运行Hadoop程序基本原理分析 分类: A1_HADOOP 2014-08-22 11:03 3462人阅读 评论(1) 收藏

    为了简化命令行方式运行作业,Hadoop自带了一些辅助类.GenericOptionsParser是一个类,用来解释常用的Hadoop命令行选项,并根据需要,为Configuration对象设置相应的 ...

  5. js中ajax连接服务器open函数的另外两个默认参数get请求和默认异步(open的post方式send函数带参数)(post请求和get请求区别:get:快、简单 post:安全,量大,不缓存)(服务器同步和异步区别:同步:等待服务器响应当中浏览器不能做别的事情)(ajax和jquery一起用的)

    js中ajax连接服务器open函数的另外两个默认参数get请求和默认异步(open的post方式send函数带参数)(post请求和get请求区别:get:快.简单 post:安全,量大,不缓存)( ...

  6. auto_create_partition

    #!/usr/bin/env python # -*- encoding: utf8 -*- import calendar import time import os import sys from ...

  7. gcc编译选项--转

    gcc提供了大量的警告选项,对代码中可能存在的问题提出警告,通常可以使用-Wall来开启以下警告:           -Waddress -Warray-bounds (only with -O2) ...

  8. Linux下图形界面调试工具kdbg安装及測试

    1.Ubuntu系统下安装 Ubuntu系统安装比較方便,直接apt-get即可 apt-get install kdbg 2.centos 安装 首先,在这个地址下下载rpm包.然后使用rpm命令安 ...

  9. PHP数组foreach循环如何实现逆序访问?

    PHP数组foreach循环如何实现逆序访问? 一.总结 1.array_reverse($array) :foreach(array_reverse($array) as $key=>$val ...

  10. Freemarker中的null判断,小坑一枚

    上次写到,在Freemarker中日期转换,可以提取成工具方法.主要是Freemarker对null的处理方式,非常坑爹.只要一个对象或对象的属性为null,就报错,虽然不影响界面显示,但控制台和日志 ...