本文閱讀前要有必定redux基礎前端
redux做爲狀態管理倉庫,在咱們前端應用中發揮着很是重要的做用,先放一張官方redux flow圖片
使用middleWare背景:咱們知道redux中數據流是同步的,不支持異步action更新或獲取數據,可是在實際項目中異步請求數據絕對是高頻出現,而且能夠說佔據了9成以上的業務場景(初始數據列表、獲取商品信息、添加購物車等等),所以redux中間件誕生了react
// store.js import {createStore,applyMiddleware,compose} from 'redux'; import thunk from 'redux-thunk'; import reducers from './reducer.js'; const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; // 用到了chrome的redux插件,因此這裏用到加強函數compose export default createStore(reducers,composeEnhancers(applyMiddleware(thunk))); // 一、利用applyMiddleware使用中間件 // 二、createStore只接受兩個參數,因此若是要引用多箇中間件applyMiddleware支持傳入數組
// actionCreators.js export const getTodoListAction => (value) => ({ type:GET_LIST, value }) export const getTodoList = () => (dispatch) => axios('api/getList').then( data => { store.dispatch(getTodoListAction(data)) }) // thunk中間件使得action返回一個函數而不是對象,從而能夠監聽延遲action的派遣或者再知足特定條件下(接口數據返回)再進行派遣
// react組件 index.js import { getTodoList } from './store/actionCreators'; import store from './store.js'; componentDidMount(){ const action = getTodoList(); store.dispatch(action); }
// store.js import {createStore,applyMiddleware,compose} from 'redux'; import createSagaMiddleware from 'redux-saga'; import reducers from './reducer.js'; import sage from './sage.js'; // 要引入saga的執行方法(其實就是異步action的方法) const sagaMiddleware = createSagaMiddleware(); // 先建立中間件 const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; // 用到了chrome的redux插件,因此這裏用到加強函數compose export default createStore(reducers,composeEnhancers(applyMiddleware(sagaMiddleware))); sagaMiddleware.run(sage); // run方法執行中間件
// saga.js // 返回的是generator函數 import { takeEvery , put} from 'redux-saga'; import superagent from 'superagent'; import { getTodoList } from './actionCreators.js'; import { GET_MY_LIST } from './actionType.js'; // mySaga方法會監聽相應type類型的action,而後作異步處理延緩派遣 function* mySaga(){ yield takeEvery(GET_MY_LIST,getMyList); // saga會在這裏攔截相應type的action並作異步處理 } function* getMyList(){ const res = yield superagent.get('/api/url'); const action = getTodoList(res); yield put(action); // 發起相應action,相似於dispatch } export default mySaga; // 這裏作個擴展,咱們知道generator中多個yield會順序執行,但咱們須要多個並行互不影響的異步操做怎麼辦? 很簡單,引入all import { all } from 'redux-saga'; export default function* rootSaga(){ yield all([ fun1(), // generator異步方法1 fun2() // generator異步方法2 ]) }
// react組件index.js import { getMyListAction } from './actionCreators.js'; import store from './store.js'; componentDidMount(){ const action = getMyListAction(); store.dispatch(action); }
// actionCreators.js import { GET_MY_LIST } from './actionType.js'; export const getMyListAction = () => ({ type:GET_MY_LIST, }) export const getTodoList = (value)=> ({ type:GET_MY_LIST, value })