redux中间件(redux-thunk、redux-saga)的使用

1、什么是redux的中间件

顾名思义中间件就是谁和谁之间,那么redux中间件中的中间指的是谁呢,其实指的就是action和store,那么action和store之间的桥梁是不是dispatch,所以redux的中间件就是对dispatch的一个封装,之前dispatch接收action的是一个对象,但是使用中间件之后还可以是一个函数,如果你使用了中间件,dispatch接收的是一个对象,它就会直接派发给store,但是如果接收到一个函数的话,dispatch就会先将函数处理完,处理好之后再派发给store。在这里处理啥呢,可以处理ajax异步请求等操作。redux中间件的流程图如下
在这里插入图片描述

2、常见的redux中间件
  • redux-thunk: 解决redux中的异步问题,将异步问题放在action中进行操作。
  • redux-saga:同样是解决redux中的异步问题,不同于redux-thunk的是,将异步问题的逻辑单独的拆分出来放到另一个文件进行管理。
3、 redux-thunk的使用

(1):安装redux-thunk

1:npm install redux-thunk --save
或
2:yarn add redux-thunk

(2):如果要做到一个从ajax获取的数据,替换store里的值,我们该怎么做呢,首先在组件中,componentDidMount生命周期内派发一个action给store,告诉store我们要做一个什么事情。

// 引入action文件中需要做的事情,这个事情我们自定义为getToDoList
import {getToDoList} from './storeThunk/actionCreators'
  componentDidMount(){
    const action = getToDoList()
    store.dispatch(action)
  }

(3):接下来我们就创建一个action文件actionCreators.js,在这里该文件是进行action操作的文件,redux-thunk也是在这体现出来的,可以将action返回一个函数,这里可以异步获取数据,再创建一个actionTypes.js,该文件是存放type类型的变量,对type类型进行管理。
actionTypes.js:

export const  INIT_LIST_ACTION = 'init_list_action'

actionCreators.js
代码如下:

import {INIT_LIST_ACTION} from './actionTypes'
import axios from 'axios'

export const getInitListAction = (data) =>({
  type:INIT_LIST_ACTION,
  data
})
// redux-thunk的体现,返回一个函数
export const getToDoList = () =>{
  return (dispatch) => {
    axios.get('/todolist').then((res)=>{
      console.log('res323',res)
      const data = res.data
      const action = getInitListAction(data)
      dispatch(action)
    })
  }
}

(4):action需要store做的事情写好之后,我们需要在storeThunk文件夹(可自定义)下创建index.js,创建一个store,就可以使用store里的方法了,例如dispatch,再将我们安装的redux-thunk引入store,我们才可以像store派发一个action函数,代码如下:

// 创建一个store 
import {createStore ,applyMiddleware ,compose} from 'redux'
import reducer from  './reducer'
import thunk from 'redux-thunk';
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose;
const enhancer = composeEnhancers(
  applyMiddleware(thunk)
);
const store = createStore(reducer,enhancer)
export default store
/**
 * createStore:创建store
 * store.dispatch() :帮我们派发action,action的内容会传递给store
 * store.getState():获取store里的所有数据
 * store.subscribe():订阅store的改变,只要store发生改变这个函数接收的回调函数就会被执行
 */

对以上出现的东西进行注解

  • applyMiddleware :首先需要redux引入applyMiddleware ,这使得我们可以使用中间件
  • composeEnhancers :这是可以使用redux-devtools插件的一个方法,需要查看点击链接,将redux-thunk引入进去的话,两个插件就可以一起使用了
    (5):创建好store之后,引入的reducer文件,那我们在storeThunk下再创建一个reducer.js,这个文件是对store传过来的state和action进行处理。代码如下
import {INIT_LIST_ACTION} from './actionTypes'
const defalutState ={
  defalutValue:'',
  list:[]
}
// reducer是一个纯函数,给定固定的输入,就一定会有固定的输出,而且不会有任何的副作用
export default (state=defalutState,action)=>{
  //将异步获取的数据action.data赋值给深拷贝的newState.list,在将新的对象return给store,store就获得一个新的数据了,改变之前的数据
  if(action.type===INIT_LIST_ACTION){
    const newState = JSON.parse(JSON.stringify(state))
    newState.list = action.data
    return newState
  }
  return state
}

4、 redux-saga的使用

那么使用redux-saga做异步获取数据来替换store里的数据怎么做呢,它也是对dispatch的封装,只不过将异步操作的部分跟action的部分单独分离一个文件出来,步骤如下
(1):安装redux-saga

1:npm install redux-saga --save
或
2:yarn add redux-saga

(2):在组件中,componentDidMount生命周期内派发一个action给store,告诉store我们要做一个什么事情。

// 引入action文件中需要做的事情,这个事情我们自定义为getToDoList
import {getInitList} from './storeThunk/actionCreators'
 componentDidMount(){
    const action = getInitList()
    store.dispatch(action)
  }

(3):同样需要创建一个action,创建一个action文件actionCreators.js,在这里该文件是进行action操作的文件
actionCreators.js


import {GET_INIT_LIST} from './actionTypes'
export const getInitList = () =>({
  type:GET_INIT_LIST
})

actionTypes.js

export const  GET_INIT_LIST = 'get_init_list'

(4):action创建好之后,redux-saga需要创建一个saga.js文件用来处理异步并派发action给store,看代码

// 引入redux-saga下的takeEvery 用来识别action中的type,
import { put, takeEvery } from 'redux-saga/effects'
import { GET_INIT_LIST } from './actionTypes'
import { getInitListAction } from './actionCreators'
import axios from 'axios'

function* getInitList() {
   const res = yield axios.get('/todolist')
   const action = getInitListAction(res.data)
   yield put(action)
}
function* mySaga() {
  yield takeEvery(GET_INIT_LIST, getInitList);
}

export default mySaga;
  • takeEvery:第一个参数用来识别action中的type,第二个参数如果是自定义的函数,用来对这个type需要做的异步操作逻辑操作
  • put :redux-saga下的函数,用来派发action,相当于dispatch,将action派发给store
  • 这个文件中的函数都建议使用Generator函数
    (5):action编写完之后,需要将action派发给store,所以我们来创建一个store,代码如下
    index.js
// 创建一个store 
import {createStore ,applyMiddleware ,compose} from 'redux'
import reducer from  './reducer'
import createSagaMiddleware from 'redux-saga'
import toDoSaga from './saga'
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(toDoSaga)
export default store
  • createSagaMiddleware:创建一个redux-saga,从而可以让我们使用redux-saga
  • sagaMiddleware.run(toDoSaga): 创建好store之后,运行这句话,就可以将6saga文件中的action派发给store了
    (6):创建好store之后,引入的reducer文件,那再创建一个reducer.js,这个文件是对store传过来的state和action进行处理。代码如下
import {INIT_LIST_ACTION} from './actionTypes'
const defalutState ={
  defalutValue:'',
  list:[]
}
// reducer是一个纯函数,给定固定的输入,就一定会有固定的输出,而且不会有任何的副作用
export default (state=defalutState,action)=>{
  if(action.type===INIT_LIST_ACTION){
    const newState = JSON.parse(JSON.stringify(state))
    newState.list = action.data
    return newState
  }
  return state
}
小总结

看了redux-thunk和redux-saga的使用步骤之后,是不是就可以很明显的看到两者的不同,redux-thunk将处理异步的操作和创建action写在一个文件里
在这里插入图片描述
而redux-saga是将action和处理异步的操作分开来管理
action:
在这里插入图片描述
saga:
在这里插入图片描述

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值