当前位置: 代码迷 >> 综合 >> Redux 中间件
  详细解决方案

Redux 中间件

热度:62   发布时间:2023-12-05 14:32:55.0

中间件概念

什么是中间件

中间件本质是就是一道函数,redux允许我们通过中间件的方式扩展和增强redux的应用,体现在action的处理逻辑上,
加载中间件之后,action会先被中间件处理,中间件在返回给reducer

开发redux的中间件

源码地址:https://github.com/qifutian/learngit/tree/main/redux%E5%8F%8A%E4%B8%AD%E9%97%B4%E4%BB%B6/react-redux-guide

redux的中间件本质是一道函数,并且是函数柯里化的函数

开发中间件的模板代码

export default store => next => action => {
     }
store是传过来的store仓库
next是函数的参数,也是一个函数,当中间件逻辑完成后,会调用next,目的是把当前action传给reducer,或是下一个中间件

注册中间件

中间件在开发完成以后资源被注册才能在redux的流程中生效

import {
    createStore,applyMiddleware} from 'redux'
import logger from './middlewares/logger'createStore(reducer,applyMiddleware(logger))
开发的logger作为参数被redux应用

开发中间件的功能,就是在触发action之后,会将对应的信息打印到控制台中

在已有项目中新建middleware文件夹,新建logger.js

export default function (){
    return function(next){
    return function(action){
    }}
}或者ES6方式export default store => next =>{
    console.log(action)console.log(action)next(action) // 必须调用next,要不然就传递不了action,reducer也接收不到
}

注册中间件
需要redux中的applyMiddleware方法

import {
     createStore, applyMiddleware } from "redux";
import RootReducer from "./reducers/root.reducer";import logger from "./middleware/logger";
export const store = createStore(RootReducer, applyMiddleware(logger));

在点击事件触发action中,会获取到action

多个中间件只需要在logger后面继续增加就好,调用顺序也是先logger,然后是之后的

加入中间件的工作流程

在这里插入图片描述

中间件异步执行action

新建thunk.js

让对应的事件延迟执行2秒

export default ({
    dispatch}) => next => action => {
    if (typeof action.type === 'increment') {
    setTimeout(()=>{
    next(action)},2000)}}

在index.js注册

import {
     createStore, applyMiddleware } from "redux";
import RootReducer from "./reducers/root.reducer";
import thunk from './middleware/thunk';import logger from "./middleware/logger";
export const store = createStore(RootReducer, applyMiddleware(logger,thunk));

export default ({
    dispatch}) => next => action => {
    // 1. 当前这个中间件函数不关心你想执行什么样的异步操作 只关心你执行的是不是异步操作// 2. 如果你执行的是异步操作 你在触发action的时候 给我传递一个函数 如果执行的是同步操作 就传递action对象// 3. 异步操作代码要写在你传递进来的函数中// 4. 当前这个中间件函数在调用你传递进来的函数时 要将dispatch方法传递过去if (typeof action === 'function') {
    return action(dispatch)}next(action)
}

常用的中间件

redux-thunk

下载 npm insatll redux-thunk

引入

import {
     createStore, applyMiddleware } from "redux";
import RootReducer from "./reducers/root.reducer";import thunk form "redux-thunk"export const store = createStore(RootReducer, applyMiddleware(thunk));

使用,异步调用

export const increment_async = payload =>dispatch => {
    setTimeout(()=>{
    dispatch(increment(payload))},2000)
}

redux-saga

redux-saga解决问题:saga可以将异步操作从Action Creator 文件中抽离出来,放在单独一个文件中
项目代码更好维护

下载 npm install redux-saga

import createSagaMidddleware from 'redux-saga';
// 创建 sagaMiddleware
const sagaMiddleware = createSagaMidddleware();export const store = createStore(RootReducer, applyMiddleware(sagaMiddleware));

使用saga接收action进行异步操作

import {
     takeEvery, put, delay } from 'redux-saga/effects';
import {
     increment } from '../actions/counter.actions';
import {
     INCREMENT_ASYNC } from '../const/counter.const';// takeEvery 接收 action
// put 触发 actionfunction* increment_async_fn (action) {
    yield delay(2000);yield put(increment(action.payload))
}export default function* counterSaga () {
    // 接收actionyield takeEvery(INCREMENT_ASYNC, increment_async_fn)
}

启动saga

import rootSaga from './sagas/root.saga';// 启动 counterSaga
sagaMiddleware.run(rootSaga)

步骤:

  1. 在index.js中引入saga中间件,调用sagaMiddleware,在redux中使用applyMiddleware方法注册
  2. 导入conunter.saga.js,在当前文件中引入saga的takeEvery接收action并绑定方法,put触发action,delay延迟调用
  3. 在index的sagaMiddleware.run(rootSaga)启动saga

redux-saga的action传参

在组件中处理方法时需要 以函数形式 <button onClick = {() => increment_async(20)}>

处理action中,export const increment_async = payload => ({type: INCREMENT_ASYNC, payload});

在counter.saga.js中,takeEvery处理的函数接收action参数,被reducer中接收到
function* increment_async_fn (action) {
yield delay(2000);
yield put(increment(action.payload))
}

在reducer中根据type类型,返回给页面

saga合并
saga可以进行拆分,更有利于维护,用all方法进行合并

import {
     all } from 'redux-saga/effects';
import counterSaga from './counter.saga';
import modalSaga from './modal.saga';export default function* rootSaga () {
    yield all([counterSaga(),modalSaga()])
}

redux-actions 中间件的使用

redux-actions解决的问题: redux流程中大量的样板读写很痛苦,使用redux-actions可以简化Action和Reducer的处理
下载 : npm install redux-actions

使用

创建Action

import {
    createAction} from 'redux-actions'
const increment_action = createAction("increment")

创建Reducer

import {
     handleActions as createReducer } from 'redux-actions'
import {
     increment_action,decrement_action } from '../actions/counter.action'const initialState = {
    count:0}
const counterReducer = createReducer({
    [increment_action]:(state,action) =>({
    count:state.count + 1})},initialState)export default counterReducer