redux之redux-thunk和redux-saga

本文閱讀前要有必定redux基礎前端

redux做爲狀態管理倉庫,在咱們前端應用中發揮着很是重要的做用,先放一張官方redux flow圖片
image.png
使用middleWare背景:咱們知道redux中數據流是同步的,不支持異步action更新或獲取數據,可是在實際項目中異步請求數據絕對是高頻出現,而且能夠說佔據了9成以上的業務場景(初始數據列表、獲取商品信息、添加購物車等等),所以redux中間件誕生了react


 redux-thunk異步action示例:

// 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);
}

redux-saga異步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
})
相關文章
相關標籤/搜索