一直覺得有些概念還離著自己比較遠,比如ES6,比如React,比如Redux,雖說這些概念早已經火的一塌糊塗,每天逛微博知乎到處都是他們的身影,但感覺好像和自己沒什麼關係。不過最近要開始一個新的項目,一個webapp,開始依然像我以前一樣,頂級組件處理處理邏輯和數據,數據通過組件屬性分發下去,邏輯通 ...
一直覺得有些概念還離著自己比較遠,比如ES6,比如React,比如Redux,雖說這些概念早已經火的一塌糊塗,每天逛微博知乎到處都是他們的身影,但感覺好像和自己沒什麼關係。不過最近要開始一個新的項目,一個webapp,開始依然像我以前一樣,頂級組件處理處理邏輯和數據,數據通過組件屬性分發下去,邏輯通過事件分發下去,這時候產生一個問題,所有的邏輯頂級組件處理,頂級組件會越來越臃腫,對於嵌套層級較多的組件,事件需要一級級的傳遞。這時候需要拆分頂級組件的邏輯,最好子組件也能操作邏輯,但數據依然只有一份,Redux好像可以解決這個問題。
Redux有四個核心內容:state、Action、Reducer和Store。
state是唯一的數據源,我們在應用內需要保證數據源的唯一。
Action定義了一系列的動作,獲取數據的操作可以在這裡處理,比如ajax之類。可以使用Action Creator定義action,Action Creator就是一個普通的函數,返回一個普通的對象,其中type欄位是必須的,其他隨意。比如定義一個發送文本消息的action:
var sendTextMsg = function(to, msg) { return { type: 'SEND_TEXT_MSG', to: to, msg: msg } }
這裡需要註意的是通常我們的Action不會是像上面的同步操作,而是非同步操作(ajax等),這時需要使用Redux提供的中間件的概念,Redux提供了一個用於此的中間件:redux-thunk。 上面的 sendTextMsg (我們加入一個延遲操作)方法需要改成:
var sendTextMsg = function(to, msg) { return function(dispatch) { setTimeout(function() { dispatch({ type: _c.actionTypes.SEND_TEXT_MSG, to: to, msg: msg }) }, 2000) } }
Reducer根據action的type和數據操作返回新的state,Redux作者建議不要直接操作state,而是始終返回新的state。
var imApp = function(state, action) { if(typeof state === 'undefined') { return initialState; } switch(action.type) { case 'SEND_TEXT_MSG': // magic code return state; case 'SEND_IMAGE_MSG': // magic code return state; default: return state; } }
Store用於將Reducer和Action聯繫起來,使用 Redux.createStore(reducer) 創建一個store。得到store後就可以訂閱reducer的動作,觸發action了。
// 定義store var store = Redux.createStore(imApp); store.subscribe(function() { store.getState() // 獲取state // magic }); store.dispatch(store.dispatch(sendTextMsg(to, con)))
如果使用redux-thunk,此處的store需要改為:
//redux-thunk源碼很短 var thunkMiddleware = function ({ dispatch, getState }) { // console.log('Enter thunkMiddleware'); return function(next) { // console.log('Function "next" provided:', next); return function (action) { // console.log('Handling action:', action); return typeof action === 'function' ? action(dispatch, getState) : next(action) } } } // applyMiddleware api var store = Redux.createStore(_t.imApp, Redux.applyMiddleware(thunkMiddleware));
下麵是我畫的一張Redux的關係圖:
本文只是我對Redux極其粗淺的理解,更多的概念我還沒有涉及到。
參考: Redux 中文文檔
新博客地址: http://darkzone.applinzi.com/