文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2022-12-22 15:00

关注

Redux中的异步操作

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

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

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

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

组件中进行异步操作

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

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

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

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

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

// store/actionCreators.jsx

import { CHANGE_BANNERS, CHANGE_RECOMMENDS } from "./constants"

export const changeBannersAction = (banners) => ({
  type: CHANGE_BANNERS,
  banners
})
export const changeRecommendsAction = (recommends) => ({
  type: CHANGE_RECOMMENDS,
  recommends
})
// store/reducer.jsx

import { 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
  }
}

在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和recommends
const mapDispatchToProps = (dispatch) => ({
  changeBanners(banners) {
    dispatch(changeBannersAction(banners))
  },
  changeRecommends(recommends) {
    dispatch(changeRecommendsAction(recommends))
  }
})

export default connect(null, mapDispatchToProps)(Category)

目前, 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)

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

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

// 定义一个返回函数的action
export const fetchHomeMultidataAction = () => {
  function foo() {
    console.log("aaa")
  }

  return foo
}
// 派发action
const mapDispatchToProps = (dispatch) => ({
  fetchHomeMultidata() {
    // 派发一个函数, 内部返回的函数自动执行
    dispatch(fetchHomeMultidataAction())
  }
})

自动执行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))
    })
  }
}

到此这篇关于Redux中进行异步操作(网络请求)的方案的文章就介绍到这了,更多相关Redux异步操作内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯