前言
大家都知道state数据不能直接改变,每次都得拷贝一份state数据,很容易忘记,在这里给大家推荐facebook开发的Immutable.js。
Immutable简介
Immutable.JS 旨在以一种高性能的方式提供不可变,以克服 JavaScript 不可变的局限性。其主要优点包括:
保证不可变
封装在 Immutable.JS 对象中的数据永远不会发生变换(mutate)。总是会返回一个新的拷贝对象。这与 JavaScript 相反,其中一些操作不会改变数据(例如,一些数组方法,包括 map,filter,concat,forEach 等),但有一些操作会改变数据(Array 的 pop,push,splice 等)。
丰富的 API
Immutable.JS 提供了一组丰富的不可变对象来封装数据(例如,Maps,Lists,Sets,Records 等),以及一系列操作它们的方法,包括 sort,filter,数据分组,reverse,flatten 以及创建子集等方法。
高性能
Immutable.JS 在实现过程中针对性能优化做了很多工作。这是非常关键的功能,因为使用不可变的数据结构可能需要进行大量昂贵的复制。尤其是对大型复杂数据集(如嵌套的 Redux state tree(状态树))进行不可变操作时,中间可能会产生很多拷贝对象,当浏览器的垃圾回收器清理对象时,这些拷贝对象会消耗内存并降低性能。
Immutable.JS 内部通过巧妙共享数据结构避免了这种情况,最大限度地减少了拷贝数据的情况。它还能执行复杂的操作链,而不会产生不必要的(且昂贵的)中间数据克隆,这些数据很快就会被丢弃。
你决不会看到这些,当然 - 你给 Immutable.JS 对象的数据永远不会发生变化。但是,它从 Immutable.JS 中生成的 intermediate 数据,可以通过链式调用序列中的数据进行自由的变换。因此,你可以拥有不可变数据结构的所有优势,并且不会产生任何潜在的(或很少)性能问题。
Immutable.js使用方法
1.安装Immutable.js
yarn add Immutable.js
2.项目中引入Immutable.js
store/reducer.js
import * as actionTypes from './actionTypes'
import {fromJS} from 'immutable'
const defaultState=fromJS({
focused:false
})
export default (state=defaultState,action)=>{
switch(action.type){
case actionTypes.SEARCH_FOCUS:
return state.set('focused',true)
case actionTypes.SEARCH_BLUR:
return state.set('focused',false)
default:
return state
}
}
大家可以 看到原先的state现在经过fromJS方法包装起来,fromJS将一个js数据转换为Immutable类型的数据,使用此方法我们就可以拿到Immutable类型的 state,同时使用set()方法可以改变state的值,而不需要考虑每次需要拷贝state的 问题。
然后在组件中引用get()f方法调state的值,
const mapStateToProps=(state)=>{
return{
focused:state.header.get('focused')
}
}
const mapDispathToProps=(dispatch)=>{
return{
handleFocus(){
dispatch(actionCreator.inputFocus());
},
handleBlur(){
dispatch(actionCreator.inputBlur());
}
}
}
export default connect(mapStateToProps,mapDispathToProps)(Header)
get()方法主要获取数据结构中的数据,也可以使用getIn()方法,
大家可能注意到header还不是通过get()方法获取到的 ,为了统一管理我们可以下载redux-immutable,
yarn add redux-immutable
然后将
import {combineReducers} from 'redux'
改为
import {combineReducers} from 'redux-immutable'
此时state便也处理成immutable数据,最后将上文的
const mapStateToProps=(state)=>{
return{
focused:state.header.get('focused')
}
}
改为
const mapStateToProps=(state)=>{
return{
focused:state.get('header').get('focused')
}
}
至此,state数据变完全处理为immutable,大家可以使用immutable统一管理state数据,更多immutable的API大家可以参考官方文档https://immutable-js.github.io/immutable-js/
网友评论