系统定制开发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"export const changeBannersAction = (banners) => ({  type: CHANGE_BANNERS,  banners})export const changeRecommendsAction = (recommends) => ({  type: CHANGE_RECOMMENDS,  recommends})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
// store/reducer.jsximport { CHANGE_BANNERS, CHANGE_RECOMMENDS } from "./constants"const initialState = {  banners: [],  recommends: []}export default function reducer(state = initialState, action) {  switch(action.type) {    case CHANGE_BANNERS:      return {...state, [banners: action.banners}    case CHANGE_RECOMMENDS:      return {...state, recommends: action.recommends}    default:       return state  }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

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

import React, { PureComponent } from 'react'import axios from 'axios'import { connect } from 'react-redux'import { changeBannersAction, changeRecommendsAction } from '../store/actionCreators'export class Category extends PureComponent {  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和recommendsconst mapDispatchToProps = (dispatch) => ({  changeBanners(banners) {    dispatch(changeBannersAction(banners))  },  changeRecommends(recommends) {    dispatch(changeRecommendsAction(recommends))  }})export default connect(null, mapDispatchToProps)(Category)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

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

import React, { PureComponent } from 'react'import { connect } from 'react-redux'export class About extends PureComponent {  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>    )  }}const mapStateToProps = (state) => ({  banners: state.banners,  recommends: state.recommends})// 表示将数据映射到About组件中export default connect(mapStateToProps)(About)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

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))export default store
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

应用之后, store.dispatch()就可以派发函数了

// 定义一个返回函数的actionexport const fetchHomeMultidataAction = () => {  function foo() {    console.log("aaa")  }  return foo}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
// 派发actionconst mapDispatchToProps = (dispatch) => ({  fetchHomeMultidata() {    // 派发一个函数, 内部返回的函数自动执行    dispatch(fetchHomeMultidataAction())  }})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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

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

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

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

import axios from "axios"export const changeBannersAction = (banners) => ({  type: CHANGE_BANNERS,  banners})export const changeRecommendsAction = (recommends) => ({  type: CHANGE_RECOMMENDS,  recommends})export const fetchHomeMultidataAction = () => {  // 派发时返回的该函数自动执行, 且传入两个参数dispatch, getState  return (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      // 获取到数据后在派发action      dispatch(changeBannersAction(banners))      dispatch(changeRecommendsAction(recommends))    })  }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发