redux之redux-thunk和redux-saga

本文阅读前要有一定redux基础

redux作为状态管理仓库,在我们前端应用中发挥着非常重要的作用,先放一张官方redux flow图片
redux之redux-thunk和redux-saga_第1张图片
使用middleWare背景:我们知道redux中数据流是同步的,不支持异步action更新或获取数据,但是在实际项目中异步请求数据绝对是高频出现,并且可以说占据了9成以上的业务场景(初始数据列表、获取商品信息、添加购物车等等),因此redux中间件诞生了


 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))); 
// 1、利用applyMiddleware使用中间件
// 2、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
})

你可能感兴趣的:(redux,redux-saga)