在处理异步情况时,可以选择使用saga中间件或者thunk。目前大部分项目都选择其中之一。
1. 恢复原始代码
首先,我们需要清除之前使用thunk的代码,恢复到原始代码状态。
2. 引入saga
我们可以使用官方文档中提供的方式引入saga:
import { createStore, applyMiddleware, compose } from 'redux'; import reducer from "./reducer"; import createSagaMiddleware from "redux-saga";
const sagaMiddleware = createSagaMiddleware();
const composeEnhancers = typeof window === 'object' && window.**REDUX_DEVTOOLS_EXTENSION_COMPOSE** ? window.**REDUX_DEVTOOLS_EXTENSION_COMPOSE**({}) : compose;
const enhancer = composeEnhancers( applyMiddleware(sagaMiddleware) );
const store = createStore( reducer, enhancer );
export default store;
注意,这里引入了一个名为sagas的文件,这个文件将用于管理saga中间件。
请注意,如果没有编写sagas文件,会出现错误。为此,我们可以参考官方文档并补充sagas.js文件:
3. 迁移异步代码
接下来,我们需要将Didmount中的异步操作移动到sagas文件中。首先,在ActionCreator中创建一个标准的Action:
通过这个操作,DidMount函数进入传统的Redux逻辑。然后,Reducers将接收并处理Action。此时,saga中间件也可以接收Action了。我们进入sagas.js文件进行处理。注意,必须使用generator函数和yield语法,以满足saga中间件的要求:
import {takeEvery} from 'redux-saga/effects'; import { GET_INIT_LIST } from './actionTypes';
function* getInitList() { console.log('abc'); }
// generator函数 ES6内容 function* mySaga() { yield takeEvery(GET_INIT_LIST, getInitList); }
export default mySaga;
按照官方文档,我们编写的sagas如上图所示。只需将要拦截的ActionType填入,并创建对应的拦截函数即可。如果不了解生成器函数,可以自行搜索相关资料。
接下来我们再来理一下逻辑:在TodoList容器组件加载完毕之后,会派发一个Action。这个Action不仅Reducers可以接收到,Sagas也可以接收到。通过使用takeEvery方法声明你要接收的Type,对应绑定的方法将被执行。这样,我们就可以完成将异步操作分离的需求。
最后,我们将异步操作移动到这个方法中。根据生成器函数的特性,可以使用yield获取res,并使用sagas提供的put来分发Action。
4. 比较
redux-saga比thunk更加复杂,提供了许多其他功能,具体可参考官方文档。除了处理异步操作,我们还可以将复杂逻辑拆分到saga中。
thunk其实只提供了Action为函数的功能,精简,如果你项目比较大,建议用saga