Immutable.js原理分析

Immutable Data 就是一旦创建,就不能再被更改的数据。对 Immutable 对象的任何修改或添加删除操作都会返回一个新的 Immutable 对象。Immutable 实现的原理是 Persistent Data Structure(持久化数据结构),也就是使用旧数据创建新数据时,要保证旧数据同时可用且不变。同时为了避免 deepCopy 把所有节点都复制一遍带来的性能损耗,Immutable 使用了 Structural Sharing(结构共享),即如果对象树中一个节点发生变化,只修改这个节点和受它影响的父节点,其它节点则进行共享。

Immutable.js的使用

安装

cnpm i immutable --save

Map的操作

import React from 'react';
import ReactDOM from 'react-dom';
import {Map} from 'immutable';//声明一个对象,这个对象要设置为不可被修改的对象
const state = {value: 'hello',list: ['html','css','js']
}//将要设置不可更改的对象,传入到Map()方法中,会返回一个新的state对象
const imState = Map(state)//将state对象设置为不可被修改的对象后,使用 get('key') 方法取值
console.log(imState.get('value'))//使用set()方法修改值,修改后会返回一个新的对象,原来的对象数据没有变化
const newImState = imState.set('value','world')console.log(imState.get('value'))
console.log(newImState.get('value'))ReactDOM.render(<div>hello</div>,document.getElementById('root'));

List的操作

import React from 'react';
import ReactDOM from 'react-dom';
import {List} from 'immutable';//声明一个数据,要将该数组设置为不可更改的数组
const arry = [1,2,3]//将数组传入 List() 中即可设置不可更改的数组对象
const imList = List(arry)//对imList做追加操作,不会对原数组做修改,会返回一个新的数组对象
const newImList = imList.push(4)console.log(imList.size,newImList.size)ReactDOM.render(<div>hello</div>,document.getElementById('root'));

fromJS的操作

import React from 'react';
import ReactDOM from 'react-dom';
import {fromJS} from 'immutable';//声明一个不可更改的对象
const state = {value: 'hello',list: ['html','css','js'],obj: {x: 1,y: {z: 2}}
}//把state传入的fromJS()中
const imState = fromJS(state)//获取imState中的值
console.log(imState.get('value'))//修改imState中的值,修改对象中的第一层属性的值,可以使用 set() 方法
const newState = imState.set('value','world')
console.log(newState.get('value'))//修改imState中更深层次的数据,需要使用 setIn() 或 updateIn() 方法
//setIn() 可以直接赋值,参数1为对象属性的层级结构,按照层级顺序编写到数组中;参数2为要赋的值
const newState1 = imState.setIn(['obj','y','z'],100)
//updateIn() 可以对原始值做修改后再返回新的值,参数1同上,参数2为修改值时用的回调函数,回调函数的参数为对象原始值
const newState2 = imState.updateIn(['obj','y','z'], val => val + 1)//获取深层对象结构的值,使用 getIn() 方法
console.log(newState1.getIn(['obj','y','z']))
console.log(newState2.getIn(['obj','y','z']))ReactDOM.render(<div>hello</div>,document.getElementById('root'));

在redux中使用immutable

使用Map操作

第1步:创建store

import {createStore} from 'redux'
import reducer from './reducer'const store = createStore(reducer)export default store

第2步:创建reducer

import {Map} from 'immutable'//使用Map()来创建原始对象,创建的原始对象为不可更改的对象
const defaultState = Map({value: ''
})const reducer = (state = defaultState, action)=>{//在执行修改state的代码中,使用 set() 方法完成修改操作,返回一个新的对象if(action.type === 'change_value'){return state.set('value',action.value)}return state
}export default reducer

第3步:创建App.js文件,用于修改redux中的数据

import React, { Component } from 'react'
import store from './store'
import Son from './Son'export default class App extends Component {constructor() {super()this.state = store.getState()store.subscribe(()=>{this.setState(store.getState())})}//文本框输入事件handleInput(e){let action = {type: 'change_value',value: e.target.value}store.dispatch(action)}render() {return (<div><input value={this.state.value} onChange={this.handleInput.bind(this)}></input><Son></Son></div>)}
}

第4步:创建Son.js用于实时显示redux中的数据

import React, { Component } from 'react'
import store from './store'export default class Son extends Component {constructor(){super()//此时使用store.getState()获取的数据为immutable处理后的对象,要使用get()方法获取具体值this.state = {value:  store.getState().get('value')}store.subscribe(()=>{this.setState({value: store.getState().get('value')})})}render() {return (<div>Son组件:{this.state.value}</div>)}
}

使用fromJS操作

App.js代码

import React, { Component } from 'react'
import store from './store'
import Son from './Son'export default class App extends Component {constructor() {super()this.state = {value: '',name: '',age: 0,h1: ''}}//提交事件handleSubmit(){let action = {type: 'reg_user',value: this.state.value,name: this.state.name,age: this.state.age,h1: this.state.h1}store.dispatch(action)}render() {return (<div><div>普通值:<input value={this.state.value} onChange={(e)=>{this.setState({value: e.target.value})}}></input></div><div>姓名:<input value={this.state.name} onChange={(e)=>{this.setState({name: e.target.value})}}></input></div><div>年龄:<input value={this.state.age} onChange={(e)=>{this.setState({age: e.target.value})}}></input></div><div>爱好:<input value={this.state.h1} onChange={(e)=>{this.setState({h1: e.target.value})}}></input></div><button onClick={this.handleSubmit.bind(this)}>提交</button><hr /><Son></Son></div>)}
}

store.js代码

import {createStore} from 'redux'
import reducer from './reducer'const store = createStore(reducer)export default store

reducer.js代码

import {fromJS} from 'immutable'//使用Map()来创建原始对象,创建的原始对象为不可更改的对象
const defaultState = fromJS({value: '',user: {name: '',age: 0,hobby: {h1: ''}}
})const reducer = (state = defaultState, action)=>{//使用fromJS中的 setIn() 方法修改数据if(action.type === 'reg_user'){return  state.setIn(['user','name'],action.name).setIn(['user','age'],action.age).setIn(['user','hobby','h1'],action.h1).set('value',action.value)}return state
}export default reducer

Son.js代码

import React, { Component } from 'react'
import store from './store'export default class Son extends Component {constructor(){super()//此时store.getState()获取到数据为复杂类型,要使用getIn()方法const storeState = store.getState();this.state = {value:  storeState.get('value'),user: {name: storeState.getIn(['user','name']),age: storeState.getIn(['user','age']),hobby: {h1: storeState.getIn(['user','hobby','h1'])}}}//监听store中的数据更新store.subscribe(()=>{const storeState2 = store.getState();this.setState({value:  storeState2.get('value'),user: {name: storeState2.getIn(['user','name']),age: storeState2.getIn(['user','age']),hobby: {h1: storeState2.getIn(['user','hobby','h1'])}}})})}render() {let {value,user} = this.statereturn (<div>Son组件:{value}<p>姓名:{user.name}</p><p>年龄:{user.age}</p><p>爱好:{user.hobby.h1}</p></div>)}
}

immutable.js笔记相关推荐

  1. js find的用法_React常用库Immutable.js常用API

    JavaScript 中的对象一般是可变的(Mutable),因为使用了引用赋值,新的对象简单的引用了原始对象,改变新的对象将影响到原始对象.如 foo={a: 1}; bar=foo; bar.a= ...

  2. js笔记(一)js基础、程序结构、函数

    大标题 小节 一.js 基础 1. javascript的组成: 2. 运行js: 3. 打印信息: 4. 关键字var: 5. js中的数据类型: 6. NaN(not a number): 7. ...

  3. php tire树,Immutable.js源码之List 类型的详细解析(附示例)

    本篇文章给大家带来的内容是关于Immutable.js源码之List 类型的详细解析(附示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 一.存储图解 我以下面这段代码为例子,画 ...

  4. php Immutable,Immutable.js详解

    这次给大家带来Immutable.js详解,使用Immutable.js的注意事项有哪些,下面就是实战案例,一起来看一下. Immutable.js在react + router + redux项目中 ...

  5. Vue.js笔记(一)

    Vue.js笔记(一) 读书笔记 Vue.js介绍 内容概要 1.1 站在巨人的肩膀上 1.1.1 MVC模式 1.1.2 MVVM模式 2.1.3 异步执行脚本 2.1.4 动态加载脚本 2.2 行 ...

  6. immutable.js中文文档

    Immutable 是什么? 关于Immutable的定义,官方文档是这样说的: Immutable data encourages pure functions (data-in, data-out ...

  7. Node.js笔记:SerialPort(串口)模块使用(基于9.x.x)

    文章目录 目的 模块安装 基础使用 扫描端口 打开端口 发送数据 接收数据 错误处理 数据解析器 SerialPort类 构造方法 属性 事件 方法 命令行工具 总结 目的 上位机与各种电路模块间常常 ...

  8. 【React】immutable.js 基础教程

    文章目录 JS中数据修改问题 介绍 常用API object转Map对象 array转List对象 JS转immutable immutable转JS Redux中集成 用它的原因是为了解决问题:解决 ...

  9. node.js笔记第一天

    nodejs笔记 web服务器和服务端js的区别 1.js都是运行在浏览器的 ECMAScript:js语法 bom:浏览器对象模型,用js去操作浏览器窗口 Dom:文档对象模型,用js去操作dom树 ...

最新文章

  1. ArcSDE建Table在ArcCatalog中不可见
  2. 为什么说_br__标签需要闭合
  3. 如何:从Spring 4.0快速入门以构建简单的REST-Like API(演练)
  4. “访问 IIS 元数据库失败”的错误信息
  5. BugkuCTF-PWN题pwn5-overflow2超详细讲解
  6. 开源:如何优雅的实现一个操作日志组件
  7. 使用jsp,tag提取字符串中的单词
  8. mac上如何将文件批量重命名的方法
  9. OEA ORM 框架中的冗余属性设计
  10. 裁员潮下,工程师该何去何从?
  11. 工业AI落地场景案例实战,飞桨EasyDL让工业更智能
  12. 智能指针的标准之争:Boost vs. Loki
  13. AR和VR,有哪些知名的开源平台
  14. Edge浏览器主页被hao123劫持怎么办?
  15. 单元测试chapter2
  16. 计算机学生如何创新,试论如何在计算机教育中培养学生的创新能力
  17. 信号与系统学习笔记(大纲)
  18. 模电学习笔记(七)——差分放大器电路(减法器)
  19. idea鼠标控制放大缩小的操作
  20. CodeForces869E The Untended Antiquity

热门文章

  1. Catalan数应用
  2. 想要成为真正优秀的程序员是不是真的很难?
  3. Impala 调用Hbase 报错 LeaseException
  4. 阿里开发者们的第13个感悟:工程师需要在循环迭代中成长
  5. NLP领域中更有效的迁移学习方法
  6. 阿里云迁云方式大汇总 1
  7. k8s 集群居然可以图形化安装了?
  8. 携程梁建章:要让元宇宙技术成为真宇宙探索、旅游的灵感来源
  9. 四大招让无处不在的工作空间成为可能?揭秘Ivanti 的战略布局
  10. 2019年程序员薪酬报告:平均年薪超70万!40岁后,这类人不“保值”了