Immutable.js使用教程记录

Posted 飞哥100

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Immutable.js使用教程记录相关的知识,希望对你有一定的参考价值。

文档:

官方 

github

认识Immutable.js

 

immutable.js的用法:

深度浅出immutable.js

笔记, immutable-js 基础操作 - 题叶, JiyinYiyong - SegmentFault

React 数据为什么要使用immutable方式?浅复制与深复制思考 - 第二人生 - SegmentFault

immutableJS一些API - 博客园

Immutable 详解及 React 中实践 - pure render - 知乎专栏

Immutable学习笔记

如何用React+Redux+ImmutableJS进行SPA开发

使用immutable和react-immutable-render-mixin优化React Native视图渲染

 

性能优化:

React移动web极致优化

React + Redux + Immutablejs开发总结

使用pureRender,setState和Immutable.js来操作state

 

案例学习:

ToDo-react-redux-immutable

用React、Redux、Immutable做俄罗斯方块

使用redux-immutable的例子:redux-immutable-examples

 [React Native]Redux的基本使用方式

 

扩展:

redux-immutable : redux定制版immutable

redux-orm :A small, simple and immutable ORM to manage relational data in your Redux store.

 

记录:

如何在Redux中使用Immutable?

将原来 Redux提供的combineReducers改由上面的库提供:

// rootReduers.js
// import { combineReducers } from \'redux\'; // 旧的方法
import { combineReducers } from \'redux-immutable\'; // 新的方法

import prop1 from \'./prop1\';
import prop2 from \'./prop2\';
import prop3 from \'./prop3\';

const rootReducer = combineReducers({
  prop1, prop2, prop3,
});


// store.js
// 创建store的方法和常规一样
import { createStore } from \'redux\';
import rootReducer from \'./reducers\';

const store = createStore(rootReducer);
export default store;

通过新的combineReducers将把store对象转化成Immutable,在container中使用时也会略有不同(但这正是我们想要的):

const mapStateToProps = (state) => ({
  prop1: state.get(\'prop1\'),
  prop2: state.get(\'prop2\'),
  prop3: state.get(\'prop3\'),
  next: state.get(\'next\'),
});
export default connect(mapStateToProps)(App);

更多详情参考:github代码

 

项目如何集成 immutable 到开发流程中? 

按照 Redux 的工作流,我们从创建 store 开始。Redux 的 createStore 可以传递多个参数,前两个是: reducers 和 initialState。

reducers 我们用 redux-immutable 提供的 combineReducers 来处理,他可以将 immutable 类型的全局 state 进行分而治之:

const rootReducer = combineReducers({
    routing: routingReducer,
    a: immutableReducer,
    b: immutableReducer
});

当然 initialState 需要是 immutable 的:

const initialState = Immutable.Map();
const store = createStore(rootReducer, initialState);

如果你不传递 initialState,redux-immutable也会帮助你在 store 初始化的时候,通过每个子 reducer 的初始值来构建一个全局 Map 作为全局 state。当然,这要求你的每个子 reducer 的默认初始值是 immutable的。

接下来,你会发现,react-router-redux的接入也要改造,因为 routerReducer 是不兼容 immutable 的,所以你必须自定义 reducer:

import Immutable from \'immutable\';
import {
    LOCATION_CHANGE
} from \'react-router-redux\';

const initialState = Immutable.fromJS({
    locationBeforeTransitions: null
});

export default (state = initialState, action) => {
    if (action.type === LOCATION_CHANGE) {
        return state.set(\'locationBeforeTransitions\', action.payload);
    }
     return state;
};
除此之外,还要让react-router-redux能够访问到挂载在全局 state 上的路由信息:

import {
    browserHistory
} from \'react-router\';
import {
    syncHistoryWithStore
} from \'react-router-redux\';

const history = syncHistoryWithStore(browserHistory, store, {
    selectLocationState (state) {
        return state.get(\'routing\').toObject();
    }
});

处理好 store 创建、reducer 集成、路由控制,接下来改处理 connect 链接,因为 connect 本身只支持 plain Object,所以需要将数据转成 connect 能支持的格式。但这并不意味着你要这么干:

@connect(state => state.toJS())
这种传递方式本质上和上面提及的只在 reducer 里使用 immutable 是一样一样的,会带来巨大的性能开销。正确的方式是,将绑定到 props 的 state 转化为属性为 immutable 的 Object 对象:

@connect(state => state.toObject())
当然,以上的例子是整个转化过去,你也可以按需绑定对应组件所关心的 state。

细心的人可能会发现,在使用 immutable 维护全局的 state 的情况下,组件 props 的校验也需要与时俱进,使用 immutable 类型校验,这就需要我们 import 专门针对 immutable 类型进行校验的库:react-immutable-proptypes,使用方法基本上和普通的 PropTypes 一致:

propTypes: {
    oldListTypeChecker: React.PropTypes.instanceOf(Immutable.List),
    anotherWay: ImmutablePropTypes.list,
    requiredList: ImmutablePropTypes.list.isRequired,
    mapsToo: ImmutablePropTypes.map,
    evenIterable: ImmutablePropTypes.iterable
}
与此同时,产生defaultProps的地方应该为:

fromJS({
    prop1: xxx,
    prop2: xxx,
    prop3: xxx
}).toObject();

 参考:http://react-china.org/t/react-redux-immutablejs/9948

 

redux使用总结:

整个应用只有一个store,用来保存所有的状态,视图不需要自己维护状态。
视图通过connect函数绑定到store,当store状态变化后,store会通知视图刷新。
触发一个action之后,会经过可能N个reducers处理,最后根reducer会将所有reducers处理之后的状态合并,然后交给storestore再通知视图刷新。

永远不要修改state!比如reducer 里不要使用 Object.assign(state, newData),应该使用 Object.assign({}, state, newData),这样才不会覆盖旧的 state,也可以使用 Babel 阶段 1 中的 ES7 对象的 spread 操作 特性中的 return { ...state, ...newData }。

 

以上是关于Immutable.js使用教程记录的主要内容,如果未能解决你的问题,请参考以下文章

使用 immutable.js 和 Facebook 流进行静态类型检查

使用 immutable.js 的 react shouldComponentUpdate 的最佳实现是啥

Immutable.js 与 Angular 2

Immutable.js - fromJS 生成 Record 代替 Map

传播运算符与 immutable.js

在 Immutable.js 中使用 React 的不可变助手