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

02-27 1063阅读 0评论

文章目录

      • Redux中的异步操作
        • 组件中进行异步操作
        • redux中进行异步操作

          Redux中的异步操作

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

          Redux中进行异步操作(网络请求)的方案,Redux中进行异步操作(网络请求)的方案,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,使用,我们,安装,第1张
          (图片来源网络,侵删)

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

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

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


          组件中进行异步操作

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

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

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

          Redux中进行异步操作(网络请求)的方案,Redux中进行异步操作(网络请求)的方案,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,使用,我们,安装,第3张
          (图片来源网络,侵删)

          创建一个组件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 (
                
          Category
          ) } } // 映射方法用于修改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 (
                

          轮播图展示

            { banners.map(item => { return item.acm}{item.title} }) }

          推荐数据展示

            { recommends.map(item => { return item.acm}{item.title} }) }
          ) } } const mapStateToProps = (state) => ({ banners: state.banners, recommends: state.recommends }) // 表示将数据映射到About组件中 export default connect(mapStateToProps)(About)

          redux中进行异步操作

          上面的代码有一个缺陷:

          Redux中进行异步操作(网络请求)的方案,Redux中进行异步操作(网络请求)的方案,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,使用,我们,安装,第4张
          (图片来源网络,侵删)

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

          事实上,网络请求到的数据也属于我们状态管理的一部分,更好的一种方式应该是将其也交给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))
              })
            }
          }
          

免责声明
本网站所收集的部分公开资料来源于AI生成和互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

发表评论

快捷回复: 表情:
评论列表 (暂无评论,1063人围观)

还没有评论,来说两句吧...

目录[+]