文檔: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 }。