Immutable

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对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Raccom

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值