文档: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 - 知乎专栏函数
如何用React+Redux+ImmutableJS进行SPA开发
使用immutable和react-immutable-render-mixin优化React Native视图渲染
性能优化:
React + Redux + Immutablejs开发总结
使用pureRender,setState和Immutable.js来操做state
案例学习:
使用redux-immutable的例子:redux-immutable-examples
扩展:
redux-immutable : redux定制版immutable
redux-orm :A small, simple and immutable ORM to manage relational data in your Redux store.
记录:
如何在Redux中使用Immutable?
目标:将state
-> 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处理以后的状态合并,而后交给store,store再通知视图刷新。永远不要修改state!好比reducer 里不要使用 Object.assign(state, newData),应该使用 Object.assign({}, state, newData),这样才不会覆盖旧的 state,也可使用 Babel 阶段 1 中的 ES7 对象的 spread 操做 特性中的 return { ...state, ...newData }。