1、安装redux-saga
yarn add redux-saga
或
npm install redux-saga -save
2、配置redux-saga
在store的index文件中引入redux-saga
import createSagaMiddleware from 'redux-saga'
并按照官方文档所说添加如下配置(https://github.com/redux-saga/redux-saga)
import { createStore, applyMiddleware, compose } from 'redux'
import reducer from './reducer'
import createSagaMiddleware from 'redux-saga'
import todoSagas from './sagas'
const sagaMiddleware = createSagaMiddleware()
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose;
const enhancer = composeEnhancers(applyMiddleware(sagaMiddleware));
const store = createStore(reducer, enhancer)
sagaMiddleware.run(todoSagas)
export default store
sagas.js (此处必须使用Generator函数)
function* mySaga() {}
export default mySaga;
3、使用
componentDidMount() {
const action = getInitList()
store.dispatch(action)
}
当常规页面使用dispatch时,action不仅会传递给reducer,还会传递给saga.js。
import { takeEvery } from 'redux-saga/effects'
import { GET_INIT_LIST } from './actionTypes'
function* getInitList() {
console.log('abc')
}
// generator 函数
function* mySaga() {
yield takeEvery(GET_INIT_LIST, getInitList);
}
export default mySaga;
此时saga.js接收到GET_INIT_LIST时,就会执行getInitList方法,注意函数为Generator函数,所以使用yield来处理异步请求,
put相当于store,将action传递给store(类似 store.dispatch(action))。
完善后的写法:
import { takeEvery, put } from 'redux-saga/effects'
import { GET_INIT_LIST } from './actionTypes'
import { initListAction } from "./actionCreators";
import axios from 'axios'
function* getInitList() {
try{
const res = yield axios.get('/list.json')
const action = initListAction(res.data)
yield put(action)
} catch(e) {
console.log('list.json 请求失败')
}
}
// generator 函数
function* mySaga() {
yield takeEvery(GET_INIT_LIST, getInitList);
}
export default mySaga;
不得不说,redux-saga远比redux-thunk复杂的多,saga有多种api。saga可以将复杂逻辑拆分管理,适合大型项目。小型项目还是建议使用redux-thunk。