1.建立store,帶有三個方法:store.dispatch,store.subscribe,store.getStateredux
import { applyMiddleware ,createStore } from 'redux'; const store = createStore( reducer, applyMiddleware(thunk, logger) );
2.view發出dispatch->action數組
del = () => { store.dispatch({ type: 'DEL', data: this.state.count - 1 }); }
3.reducer處理action數據
每次dispatch後return的數據即store.getState()獲得的數據,即一個新的state.
因此state是一個對象,每次都是上次返回的值.
因此用Object.assign({}, state, {count: action.data})服務器
export default (state = {}, action) => { switch (action.type) { // state即返回的新狀態,新的state即本次的返回值,因此每次都是往空的對象裏,先推state,再新增屬性或改變原來屬性的值 case 'ADD': return Object.assign({}, state, {count: action.data}); case 'ADD2': return Object.assign({}, state, {count: action.data}); case 'ADD3': return Object.assign({}, state, {count: action.data}); case 'DEL': return Object.assign({}, state, {count: action.data}); case 'AJAX': return Object.assign({}, state, {res: action.data.res}); default: return { count: 0, res: 'aaaa' }; } }
4.view層經過store.subscribe()方法設置監聽函數,一旦state發生變化,就會自定執行這個函數.
在這個函數裏setState,就會觸發整個組件的render.app
store.subscribe(() => { // subscribe即,每一次dispatch,都會觸發reducer處理數據,即觸發store.subscribe this.setState({ count: store.getState().count, // reducer返回新的state,即state的值被改變state = 1 res: store.getState().res }); });
1.用戶發出Action,Reducer函數算出新的State,View從新渲染.
2.異步操做怎麼辦? Action發出之後,Reducer當即算出State,這叫作同步;Action發出之後,過一段時間再執行Reducer,這就是異步.
怎樣才能Reducer在異步操做結束後自動執行呢?這就要用到新的工具:中國件(middleware)
3.中間件
只有發送Action的這個步驟,即store.dispatch()方法,能夠添加功能.
能夠對store.dispatch進行以下改造.異步
let next = store.dispatch; store.dispatch = function dispatchAndLog(action) { console.log('dispatching', action); next(action); console.log('next state', store.getState()); }
上面代碼中,對store.dispatch進行了重定義,在發送Action先後添加了打印功能,這就是中間件的雛形.
中間件就是一個函數,對store.dispatch方法進行了改造,在發出Action和執行Reducer這兩步之間,添加了其餘功能.
4.中間件的用法
redux-logger提供一個生成器createLogger,能夠生成日誌中間件logger,而後,將它放在applyMiddleware方法中,
傳入createStore方法,就完成了store.dispatch()的功能加強.函數
import { applyMiddleware ,createStore } from 'redux'; import { createLogger } from 'redux-logger'; import thunk from 'redux-thunk'; const logger = createLogger(); const store = createStore( reducer, applyMiddleware(thunk, logger) );
5.applyMiddleware
applyMiddleware是Redux的原生方法,做用是將全部中間件組成一個數組,依次執行.
6.異步操做的基本思路
操做開始時,送出一個Action,觸發State更新爲'正在操做'狀態,從新渲染.
操做結束後,再送出一個Action,觸發State更新爲'操做結束',view再一次從新渲染.工具
1.異步操做至少要送出兩個Action,用戶觸發第一個Action,這個跟同步操做同樣,沒有問題.
如何才能在操做結束時,系統自動送出第二個Action呢?this
add3 = () => { store.dispatch(dispatchAction(this.state.count + 3)); } function dispatchAction(count) { return (dispatch) => { dispatch({ type: 'ADD3', data: count }); } }
dispatchAction是一個Action Creater,返回一個函數,這個函數執行後,發出一個action,而後執行異步操做,拿到結果後,再次dispatch,發出一個Action.
dispatchAction返回了一個函數,而普通的action creator默認返回一個對象.
返回的函數的參數是dispatch和getState這兩個redux方法.
action是由store.dispatch方法發送的,而store.dispatch方法正常狀況下,參數只能是對象,不能是函數.
這時,就使用redux-thunk中間件,改造dispatch,使得後者能夠接受函數做爲參數.spa
1.首先,這是個關於action creator的解釋.
什麼是action creator? 返回action的函數.
爲何要用action creator?圖個方便吧.日誌
function changeNum(count) { return { type: 'ADD2', data: count } } add2 = () => { store.dispatch(changeNum(this.state.count + 2)); }
2.Thunk的作法就是擴展了這個action creator.Thunk容許action creator返回一個函數,並且這個函數第一個參數是dispatch.因此不光改造action creator,若是你要用thunk,你還要把它放進middleware裏去,這樣函數類型的action就被thunk middleware捕獲,根據你的函數邏輯,再去dispatch常規的action.這樣Async Action其實就是發Ajax以前dispatch一發,收到服務器響應後dispatch一發,報錯的話再來dispatch一發.