0


Redux中进行异步操作(网络请求)的方案

文章目录

Redux中的异步操作

在之前简单的案例中,redux中保存的counter是一个本地定义的数据

我们可以直接通过同步的操作来dispatch action,state就会被立即更新。

但是真实开发中,redux中保存的很多数据可能来自服务器,我们需要进行异步的请求,再将数据保存到redux中。

在之前学习网络请求的时候我们讲过,发生网络请求我们有两种方案, 可以直接在组件的钩子函数中发送网络请求, 再将数据存放到store中; 也可以直接在store中发生网络请求


组件中进行异步操作

网络请求可以在class组件的生命周期函数componentDidMount中发送,所以我们可以有这样的结构:

在这里插入图片描述

我现在完成如下案例操作:

创建一个组件Category, 在该组件中发送网络请求, 获取banners和recommends的数据;

在About组件中展示banners和recommends的数据;

首先需要创建要派发的action, 以及对应的reducer

// store/actionCreators.jsximport{CHANGE_BANNERS,CHANGE_RECOMMENDS}from"./constants"exportconstchangeBannersAction=(banners)=>({type:CHANGE_BANNERS,
  banners
})exportconstchangeRecommendsAction=(recommends)=>({type:CHANGE_RECOMMENDS,
  recommends
})
// store/reducer.jsximport{CHANGE_BANNERS,CHANGE_RECOMMENDS}from"./constants"const initialState ={banners:[],recommends:[]}exportdefaultfunctionreducer(state = initialState, action){switch(action.type){caseCHANGE_BANNERS:return{...state,[banners: action.banners}caseCHANGE_RECOMMENDS:return{...state,recommends: action.recommends}default:return state
  }}

在Categroy组件中发送网络请求, 并将store中的banners和recommends修改为网络请求后的数据

import React,{ PureComponent }from'react'import axios from'axios'import{ connect }from'react-redux'import{ changeBannersAction, changeRecommendsAction }from'../store/actionCreators'exportclassCategoryextendsPureComponent{componentDidMount(){// 发送网络请求, 获取到banners和recommends数据
    axios.get("http://123.207.32.32:8000/home/multidata").then(res=>{const banners = res.data.data.banner.list
      const recommends = res.data.data.recommend.list
      console.log(banners, recommends)// 调用映射过来的方法, 修改banners和recommends this.props.changeBanners(banners)this.props.changeRecommends(recommends)})}render(){return(<div>Category</div>)}}// 映射方法用于修改store中的banners和recommendsconstmapDispatchToProps=(dispatch)=>({changeBanners(banners){dispatch(changeBannersAction(banners))},changeRecommends(recommends){dispatch(changeRecommendsAction(recommends))}})exportdefaultconnect(null, mapDispatchToProps)(Category)

目前, store中存放的就是网络请求获取到的数据, 接下来就在About页面进行展示

import React,{ PureComponent }from'react'import{ connect }from'react-redux'exportclassAboutextendsPureComponent{render(){// 在props中获取到映射过来的数据const{ banners, recommends }=this.props

    return(<div><h2>轮播图展示</h2><ul>{
            banners.map(item=>{return<li key={item.acm}>{item.title}</li>})}</ul><h2>推荐数据展示</h2><ul>{
            recommends.map(item=>{return<li key={item.acm}>{item.title}</li>})}</ul></div>)}}constmapStateToProps=(state)=>({banners: state.banners,recommends: state.recommends
})// 表示将数据映射到About组件中exportdefaultconnect(mapStateToProps)(About)

redux中进行异步操作

上面的代码有一个缺陷:

我们必须将网络请求的异步代码放到组件的生命周期中来完成;

事实上,网络请求到的数据也属于我们状态管理的一部分,更好的一种方式应该是将其也交给redux来管理;

在这里插入图片描述

但是在redux中如何可以进行异步的操作呢?

答案就是使用中间件(Middleware), 如果学习过Express或Koa框架的小伙伴对中间件的概念一定不陌生;

由于在正常情况下,

store.dispatch()

只能派发一个对象, 不能派发函数; 如果dispatch想要派发函数, 我们必须要使用中间件对该store进行增强

**

使用中间件, 在redux中发送网络请求

**

首先安装redux-thunk库, 引入中间件

安装redux-thunk库:

npm i redux-thunk

, 在该库中有一个中间件thunk, 如下方式应用thunk中间件

import{ createStore, applyMiddleware }from"redux";import reducer from"./reducer";// 导入中间件import thunk from"redux-thunk";// 应用中间件const store =createStore(reducer,applyMiddleware(thunk))exportdefault store

应用之后,

 store.dispatch()

就可以派发函数了

// 定义一个返回函数的actionexportconstfetchHomeMultidataAction=()=>{functionfoo(){
    console.log("aaa")}return foo
}
// 派发actionconstmapDispatchToProps=(dispatch)=>({fetchHomeMultidata(){// 派发一个函数, 内部返回的函数自动执行dispatch(fetchHomeMultidataAction())}})

自动执行action中的返回的函数时, 会传给这个函数一个dispatch函数和getState函数;

dispatch函数

: 用于我们之后再次派发action;

getState函数

: 考虑到我们之后的一些操作需要依赖原来的状态,调用getState函数可以让我们可以获取之前的一些状态;

我们就可以在返回的该函数中, 编写异步的网络请求相关代码

import axios from"axios"exportconstchangeBannersAction=(banners)=>({type:CHANGE_BANNERS,
  banners
})exportconstchangeRecommendsAction=(recommends)=>({type:CHANGE_RECOMMENDS,
  recommends
})exportconstfetchHomeMultidataAction=()=>{// 派发时返回的该函数自动执行, 且传入两个参数dispatch, getStatereturn(dispatch, getState)=>{
    axios.get("http://123.207.32.32:8000/home/multidata").then(res=>{const banners = res.data.data.banner.list
      const recommends = res.data.data.recommend.list

      // 获取到数据后在派发actiondispatch(changeBannersAction(banners))dispatch(changeRecommendsAction(recommends))})}}

本文转载自: https://blog.csdn.net/m0_71485750/article/details/126754159
版权归原作者 蓝桉cyq 所有, 如有侵权,请联系我们删除。

“Redux中进行异步操作(网络请求)的方案”的评论:

还没有评论