Redux-Thunk中间件主要是用来进行异步触发dispatch,比如我们常见的Ajax需要在网络请求返回后进行dispatch
示例代码中我们使用了Fetch这个Ajax工具
//Action export const getBugsWithPage = () => { let actionObject = { type: type, bugs: jsonData } //异步Ajax请求 fetch(url, {method: "GET"}) .then((res) => { return actionObject <==这里return是错误的,因为是在回调函数内部 }) };
可以看到,如果我们想在ajax返回的回调函数里进行return,是没办法对Action进行Retrun的,如果写在外部,又会在Ajax还未执行完毕被顺序执行
所以我们需要引入Redux的Action Creator的概念,既是返回值为Action的函数,例如使用前dispatch内部为一个包含有type的Action 对象
/* 使用前 */ dispatch({ type: ‘change_name’, name: ‘Peter’, }); dispatch({ type: ‘change_name’, name: ‘Ryan’, });
如果我们写一个changeName函数用来生成对象,那么changeName就是Action Creator
const changeName = (name)=>({ type: ‘change_name’, name: name }) /* 使用后 */ dispatch(changeName(‘Peter’)); dispatch(changeName(‘Ryan’));
参见 Redux-Thunk官方文档
// 1+2 会在代码执行时马上被运算 // x === 3 let x = 1 + 2; // 1+2被延迟运算 // 因为我们把计算1+2作为一个方法的返回值,而foo指向这个方法,只有foo被以方法执行时才会计算1+2 // foo 就可以为被称为 thunk! let foo = () => 1 + 2;
Redux官网说,action就是Plain JavaScript Object。Thunk允许action creator返回一个函数
所以说Thunk就是通过中间件改造了Redux的Action Creator,进行延迟发送Dispatch,这个Creator其可以将dispatch和Store的getState作为参数引入,从而达到异步调用
//Action const getBugsWithPage = (jsonData) => ( { type: type, bugs: jsonData } ); //Thunk Action export const fetchBugs = () => { return (dispatch, getState) => { //异步Ajax请求 fetch(url, {method: "GET"}) .then((res) => { //从返回的Promise里得到json return res.json() }) .then((json) => { //从Json里拿到数据再去Dispatch Action dispatch(getBugsWithPage(json)) }) } };
Action和 Action Creator的区别主要是返回值不同,以及能否接触到Store的dispatch方法
方法 | 返回值 | 参数 |
---|---|---|
Action | 一个包含有type的Object | 和dispatch是独立的,无法互相接触 |
Thunk Action | 返回值为一个入参为dispatch的函数 | 可以通过返回的函数异步进行dispatch,并且可以在action中获取到Store里的state |
也就是说Action Creator返回值是 函数 而不是Object
//Action Creator export const fetchBugs = () => { //返回一个方法 return (dispatch) => { ...可以在任意位置调用dispatch... } };
使用Redux-Thunk需要在中间件中配置
import thunk from "redux-thunk"; // redux-thunk 支持 dispatch function,并且可以异步调用它 import createLogger from "redux-logger"; import {createStore, applyMiddleware, compose} from "redux"; //调用日志打印方法 const loggerMiddleware = createLogger(); //创建一个中间件集合,注意thunk最好配置在第一个,因为中间件是顺序敏感的 const middleware = [thunk, loggerMiddleware]; const finalCreateStore = compose( applyMiddleware(...middleware) )(createStore); export default finalCreateStore