Redux-thunk中间件
2022-03-20 本文已影响0人
泡杯感冒灵
如果我们把异步请求或者一些非常复杂的逻辑,都放到组件里,这个组件会显得过于臃肿,这个时候,我们可以把异步请求和非常复杂的逻辑,移到其他地方进行统一管理,比如actionCreators里,Redux-thunk中间件可以使我们把异步请求或非常复杂的逻辑放到action去处理,Redux-thunk是 Redux的中间件。使用步骤如下:
- 安装Redux-thunk
npm install redux-thunk - 创建store的时候,使用Redux-thunk
import { createStore, applyMiddleware } from 'redux';
import reducer from "./reducer";
import thunk from 'redux-thunk'
const store = createStore(reducer , applyMiddleware(thunk))
- 配置好Redux-thunk中间件环境之后,使得我们可以action里去写异步的代码了,之前创建一个action只能是一个JS对象,现在当使用了Redux-thunk中间件之后,即使action是一个函数,也可以通过store.dispatch把这个函数,发送给store了。实际上store只能接收对象,当store发现发送的action是一个函数的时候,就自动执行一下action对应的这个函数。
// actionCreators.js
// 正常情况下,函数应该是return出一个action对象
// 但是使用redux-thunk之后,可以return出一个action函数了
export const getTodoList = () => {
// action对应的函数,会自动接收store.dispatch方法作为参数。
return (dispatch) => {
axios.get('/list.json').then((res)=>{
const data = res.data;
// 异步请求到数据后,需要更新store,又需要走一遍redux的流程
const action = initListAction(data);
// dispatch方法,已经作为参数自动传了进来
dispatch(action);
})
}
}
// TodoList.js
componentDidMount(){
const action = getTodoList();
store.dispatch(action);
}
什么是Redux的中间件?
image.png
- 中间件其实指的是 Action和Store之间,是对dispatch方法的封装或者说是升级,没有中间件的时候,dispatch方法把接收到的对象传递给Store,使用了Redux-thunk中间件之后,对dispatch方法进行了升级,当调用dispatch方法给dispatch方法传递的参数是一个对象的时候,就会把对象直接传递给Store,跟之前写一个对象,利用Store.dispatch传递给Store没有任何区别,但是假设传给dispatch方法是一个函数的时候,因为dispatch方法已经升级了,它不会直接把这个方法直接传递给Store,它会让这个函数先执行,执行完以后,需要调用Store的时候,函数再去调用Store。所以dispatch会根据参数的不同做不同的事情。
升级前,dispatch方法只能接收一个对象,升级后,即可以接收对象也可以接收函数,是通过Redux-thunk中间件对它进行升级的。
所以redux中间件的原理非常简单,就是对store的dispatch方法进行了升级,之前dispatch方法只能接受一个对象,升级后,即可以接收对象,又可以接收函数了。我们这里是用的redux-thunk中间件对它进行升级。
实际上redux的中间件很多,比如redux-logger可以记录action每次派发的日志。redux-saga也是管理redux应用异步操作的中间件,它跟redux-thunk的区别是,redux-thunk是把异步操作放入action里操作,而redux-saga的设计思想是单独把异步逻辑拆分出来,放入另一个文件里进行管理。
使用redux-thunk,同时还使用redux-devtools的配置
// redux-thunk是创建store的时候使用,引入applyMiddleware方法,引入thunk
import { createStore,applyMiddleware, compose } from "redux";
import thunk from 'redux-thunk';
import reducer from './reducer';
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(reducer, /* preloadedState, */ composeEnhancers(
applyMiddleware(thunk)
));
export default store;