如何在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 }。
相關文章
相關標籤/搜索