如何在Redux中使用Immutable.js及学习资料整理

文档:html

官方 react

githubgit

认识Immutable.jsgithub

 

immutable.js的用法:web

深度浅出immutable.jsredux

笔记, immutable-js 基础操做 - 题叶, JiyinYiyong - SegmentFaultsegmentfault

React 数据为何要使用immutable方式?浅复制与深复制思考 - 第二人生 - SegmentFault性能优化

immutableJS一些API - 博客园react-router

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 }。
相关文章
相关标签/搜索