Immutable_update immutable object in array-程序员宅基地

技术标签: react.js  前端  React  

Immutable


每次修改Immutable对象都会创建一个新的不可变对象,在新对象上操作都不会影响到原对象的数据


深拷贝与浅拷贝

浅拷贝

只复制引用,不复制一个新的对象

arr = { }; arr2 = arr

Object.assign() 只是一级属性复制,只比浅拷贝多了一层

深拷贝

复制一个新的对象

const obj1 = JSON.parse(JSON.stringify(obj)) 数组、对象都好用 (缺点:不能有undefined)



Immutable优化性能

Immutable实现的原理是Persistent Data Structure(持久化数据结构),也就是使用旧数据创建新数据

要保证旧数据同时可用且不变。同时要避免deepCopy把所有节点都复制一遍带来的性能消耗

Immutable使用了Structural Sharing(结构共享),即如果对象树中一个节点发生变化,只修改这个节点和受它影响的父节点,

其他节点进行共享




Map

Map方法将对象数据类型封装成Immutable对象

get(‘key’) 获取对象中的键为key的值

set(‘key’,‘value’) 设置对象中键为key的条目的值为value

Immutable对象.toJS() 将Immutable对象转换成普通的js对象

Immutable对象每次操作都会返回一个新的深拷贝的对象

同时支持链式操作

// eg:
import {
     Map, List } from 'immutable'
const obj = {
    
      name:'cc',
      age:20
    }
const oldImmuObj = Map(obj)
const newImmuObj = oldImmuObj.set('name','raccon').set('age',21)
console.log(newImmuObj,newImmuObj.get('name'))

当对象中嵌套对象是 通过Map只能转换一层Immutable对象 里面嵌套的对象不为Immutable对象结构

所以需要多层封装

const obj = Map({
    
      name:'cc',
      age:20,
      filter:Map({
    
        text:'',
        up:true,
        down:false
      })
})

多层封装的好处 :因为react中对象数据只要更新就会更新所有需要用到这个对象的组件

当我们只需要更新其中一部分时 比如 父组件的属性obj中的name更新 但是传入子组件的filter对象没有更新

此时应该让子组件不更新来节省性能 但是只要对象发生了改变均会重新渲染

但如果对象是Immutable对象 改变name时其他属性均不会改变(地址也不变)

因此可以在子组件的shouldComponentUpdate中进行比较来判断子组件是否需要更新

// eg:

import React, {
     Component } from 'react'

class Child extends Component {
    
  shouldComponentUpdate(nextProps, nextState){
    
    if(this.props.filter === nextProps.filter){
    
      return false
    }
    return true
  }
  render() {
    
    return (
      <div>Child</div>
    )
  }
}

setIn

当对象结构层次较多时需要多层的get才能获取到

可以通过Immutable.setIn()来设置深层的对象属性

 const obj = Map({
    
      name:'cc',
      age:20,
      filter:Map({
    
        text:'',
        up:true,
        down:false
      })
    })
    const oldImmuObj = Map(obj)
    const newImmuObj = oldImmuObj.setIn(['name'],'raccon').setIn(['filter','text'],'文本') 
    				// 第一个参数为数组 数组中为需要进入的结构,第二个参数为修改的内容
    console.log(newImmuObj,newImmuObj.get('name'))




List

List方法将数组数据类型封装为Immutable数组

Immutable数组拥有原生数组的所有方法 且调用方法返回的都是以一个深拷贝的数组

不会影响旧的数组数据结构

const arr = List([1,2,3])

const arr2 = arr.push(4)

console.log(arr,arr2)

updateIn

Immutable数组也有update方法修改浅层数据

当数组结构层次较多时

可以通过Immutable.updateIn()来设置深层的数组属性

const arr = List([1,2,3,List([4,5,6])])
    const brr = arr.updateIn([3],(list) => list.push(3))
    	// 第一个参数为数组 数组中为需要进入的结构,可以为键也可以为索引,第二个参数为回调函数 返回值为修改后的数组
    console.log(brr);




fromJS - toJS

实际情况下不知道接收到的数组是什么结构

可以用 普通对象.fromJS() 将数据转化为Immutable对象

当多层结构嵌套时也会将内层数据结构转换为Immutable数据结构

操作完成后用 Immutable对象.toJS() 转换为原生js对象

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Raccon_/article/details/123666754

智能推荐

国产免费数据库建模工具EZDML3.24发布 支持生成和预览vue文件_vue 数据模型软件-程序员宅基地

文章浏览阅读2.3k次。国产免费数据建模和代码生成工具,新版增加了生成vue的JS脚本模板,默认采用ElementUI作为template界面_vue 数据模型软件

1005 继续(3n+1)猜想(python)_phython 3n+1问题-程序员宅基地

文章浏览阅读122次。卡拉兹(Callatz)猜想已经在1001中给出了描述。在这个题目里,情况稍微有些复杂。当我们验证卡拉兹猜想的时候,为了避免重复计算,可以记录下递推过程中遇到的每一个数。例如对n=3进行验证的时候,我们需要计算 3、5、8、4、2、1,则当我们对n=5、8、4、2 进行验证的时候,就可以直接判定卡拉兹猜想的真伪,而不需要重复计算,因为这 4 个数已经在验证3的时候遇到过了,我们称 5、8、4、2 是被 3“覆盖”的数。我们称一个数列中的某个数n为“关键数”,如果n不能被数列中的其他数字所覆..._phython 3n+1问题

jupyter下的python基本使用和信号处理编程_jupyterlab fft-程序员宅基地

文章浏览阅读1.5k次。jupyter下的python基本使用和信号处理编程简介:jupyter notebook是一种 Web 应用,能让用户将说明文本、数学方程、代码和可视化内容全部组合到一个易于共享的文档中。它可以直接在代码旁写出叙述性文档,而不是另外编写单独的文档。也就是它可以能将代码、文档等这一切集中到一处,让用户一目了然。实验环境:腾讯云服务器centos7一、安装jupyter notebook..._jupyterlab fft

Notepad++ 安装XML Tools插件格式化XML文件-程序员宅基地

文章浏览阅读7.8k次,点赞3次,收藏5次。Notepad++ 安装XML Tools插件格式化XML文件Ritchie_Li2022.02.06 20:37:12字数 183阅读 0编辑文章1. 打开Notepad++ 软件2. 选择插件,选择“插件管理”3. 搜索 XML Tools,找到该插件后,勾选该文件,点击“安装”在Notepad++ 中安装,如果没有成功,可以在多尝试2次,我是第3次成功的,具体原因不知,但有的电脑一次就能安装成功的。4. 安装的进入如下:5.成功之后,插件栏显示6. 格式化XML文件, 单击 "_xml tools

Linux驱动开发———imx6ull的pinctrl子系统源码分析_0x4001b8b0-程序员宅基地

文章浏览阅读1.2k次,点赞3次,收藏21次。目录前言前言 最近在配置pinctrl时,配置了引脚复用寄存器的SION位,配置如下图中的所示,0x4001b8b0中的第30位表示SION位 按照个人理解,imx6ull在设备树中配置的pinctrl节点,后面所带的值应该为配置寄存器的值,而SION位是复用寄存器的第三十位..._0x4001b8b0

TCP三次握手四次挥手及各状态解释_计算机网络中seq是什么意思-程序员宅基地

文章浏览阅读2.1k次,点赞2次,收藏5次。常说的三次握手和四次挥手的意思就是TCP建立连接和断开连接的过程下图为TCP三次握手和四次挥手的过程图状态或符号解释seq(sequence number),序列号,用来标记数据段的顺序,TCP把连接中发送的数据字节都编上一个序号,第一个字节的编号由本地随机产生ack(acknowlege number),确认号,指的是期望接收到下一个字节的编号,因此当前报文段最后一个字节的编号+1即为确认号ACK(acknowledgement),确认,当ACK=1确认号字段才有效,ACK=0确认号无效S_计算机网络中seq是什么意思

随便推点

(转)基于MVC4+EasyUI的Web开发框架经验总结(10)--在Web界面上实现数据的导入和导出...-程序员宅基地

文章浏览阅读166次。http://www.cnblogs.com/wuhuacong/p/3873498.html数据的导入导出,在很多系统里面都比较常见,这个导入导出的操作,在Winform里面比较容易实现,我曾经在之前的一篇文章《Winform开发框架之通用数据导入导出操作》介绍了在Winform里面的通用导入导出模块的设计和开发过程,但在Web上我们应该如何实现呢?本文主要介绍利用MVC4+Eas...

14.JS语句和注释,变量和数据类型-程序员宅基地

文章浏览阅读112次。1.JavaScript 语句(1)语句的作用(2)语句标识符2.代码和代码块儿(1)代码(2)代码块3.分号、空格和拆行(1)分号(2)空格(3)拆行4.单行注释和多行注释5.JS变量6.创建变量7.JS 数据类型(1)值类型(基本类型):(2)引用数据类型(对象类型):(3)动态类型8.字符串、数字、布尔、数组和对象等(1)字符串(2)数字(3)布尔(4)数组(5)对象...

C语言ASCLL码_c语言 \ ascll-程序员宅基地

文章浏览阅读2.1k次。C语言ASCLL码表介绍_c语言 \ ascll

Linux那些事儿之我是U盘(37)彼岸花的传说(五)_unsigned soft : 1;-程序员宅基地

文章浏览阅读4.1k次。 燕子去了,有再来的时候;杨柳枯了,有再青的时候;桃花谢了,有再开的时候;老婆离了,有再找的时候,孩子跑了,有回来的时候;煮熟的鸭子飞了,有飞回来的时候.一个函数没讲完就跳走了,有再回来的时候.其实,那些人,那些事,终究不曾远离.于是,她再一次进入我们的视野. 她就是usb_stor_control_thread().唤醒她的是来自queuecommand的up(&(us->sema)_unsigned soft : 1;

usb-serial controller d感叹号_usb serial converter驱动感叹号-程序员宅基地

文章浏览阅读4k次,点赞6次,收藏12次。2. 安装正确的驱动程序:USB-Serial设备通常需要安装驱动程序才能正常工作。这些驱动程序通常可从设备制造商的官方网站下载。请确保下载并安装与您的操作系统兼容的最新驱动程序。解决:1. 确认设备已正确连接:检查USB-Serial设备是否正确插入计算机的USB接口,并确保插头没有松动或损坏。感叹号可能是对于USB-Serial设备发生的问题或错误的表达。这可能是指设备无法被识别、驱动安装问题、通信错误等。_usb serial converter驱动感叹号

Laravel定时任务_laravel 停止schedule:run-程序员宅基地

文章浏览阅读576次。Laravel 定时任务首先:Laravel 制定定时任务很简单的!在app/console 文件夹下面,执行 php artisan make:console TestSchedule,他会生成TestSchedule.php这个文件TestSchedule.php,这个文件写你要定时执行的代码逻辑;class TestSchedule extends Command { //..._laravel 停止schedule:run