Redux工具包 - Redux Toolkit的异步操作(发送网络请求)

Posted 学全栈的灌汤包

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redux工具包 - Redux Toolkit的异步操作(发送网络请求)相关的知识,希望对你有一定的参考价值。

Redux Toolkit异步操作

在之前的开发中,我们通过redux-thunk中间件让dispatch中可以进行异步操作, 其实Redux Toolkit工具包默认已经给我们集成了Thunk相关的功能, 我们可以通过createAsyncThunk函数创建一个异步的action

createAsyncThunk函数有参数:

参数一: 传入事件类型type

参数二: 传入一个函数, 该函数可以执行异步操作, 甚至可以直接传入一个异步函数

export const fetchHomeMultidataAction = createAsyncThunk("fetch/homemultidata", async () => 
  const res = await axios.get("http://123.207.32.32:8000/home/multidata")
  const banners = res.data.data.banners.list
  const recommends = res.data.data.recommends.list
)f

当createAsyncThunk创建出来的action被dispatch时,会存在三种状态:

pending: action被发出,但是还没有最终的结果;

fulfilled: 获取到最终的结果(有返回值的结果);

rejected: 执行过程中有错误或者抛出了异常;

我们可以在createSlice的entraReducer中监听这些结果:

注意: 我们创建的一部action: fetchHomeMultidataAction返回的结果, 会被传到下面监听函数的actions参数中,

通过actions.payload获取(也可以对actions进行结构, 直接获取payload)

// extraReducers中针对异步action, 监听它的状态
extraReducers: 
  // 处于padding状态时回调
  [fetchHomeMultidataAction.pending](state, actions) 
    console.log("正处于pending状态")
  ,
  // 处于fulfilled状态时回调
  [fetchHomeMultidataAction.fulfilled](state, actions) 
    console.log("正处于fulfilled状态")
  ,
  // 处于rejected状态时回调
  [fetchHomeMultidataAction.rejected](state, actions) 
    console.log("正处于rejected状态")
  

演示网络请求的流程:

方式一:

在home.js中, 通过createAsyncThunk函数创建一个异步的action

再在extraReducers中监听这个异步的action的状态, 当他处于fulfilled状态时, 获取到网络请求的数据, 并修改原来state中的数据

import  createSlice, createAsyncThunk  from "@reduxjs/toolkit"
import axios from "axios"

// 创建一个异步的action
export const fetchHomeMultidataAction = createAsyncThunk("fetch/homemultidata", async () => 
  const res = await axios.get("http://123.207.32.32:8000/home/multidata")
  // 返回结果会传递到监听函数的actions中
  return res.data
)

const homeSlice = createSlice(
  name: "home",
  initialState: 
    banners: [],
    recommends: []
  ,
  // extraReducers中针对异步action, 监听它的状态
  extraReducers: 
    [fetchHomeMultidataAction.fulfilled](state,  payload ) 
      // 在fulfilled状态下, 将state中的banners和recommends修改为网络请求后的数据
      state.banners = payload.data.banner.list
      state.recommends = payload.data.recommend.list
    
  
)

export default homeSlice.reducer

方式二:

如果我们不想通过在extraReducers在监听状态, 再修改state这种方法的话, 还有另外的一种做法

我们创建的fetchHomeMultidataAction这个异步action是接受两个参数的

  • 参数一, extraInfo: 在派发这个异步action时, 如果有传递参数, 会放在extraInfo里面
  • 参数二, store: 第二个参数将store传递过来

这样我们获取到结果后, 通过dispatch修改store中的state, 无需再监听异步action的状态

import  createSlice, createAsyncThunk  from "@reduxjs/toolkit"
import axios from "axios"

// 创建一个异步的action
export const fetchHomeMultidataAction = createAsyncThunk(
  "fetch/homemultidata", 
  // 有传递过来两个个参数, 从store里面解构拿到dispatch
  async (extraInfo,  dispatch ) => 
    // 1.发送网络请求获取数据
    const res = await axios.get("http://123.207.32.32:8000/home/multidata")
    // 2.从网络请求结果中取出数据
    const banners = res.data.data.banner.list
    const recommends = res.data.data.recommend.list
		// 3.执行dispatch, 派发action
    dispatch(changeBanners(banners))
    dispatch(changeRecommends(recommends))
  
)

const homeSlice = createSlice(
  name: "home",
  initialState: 
    banners: [],
    recommends: []
  ,
  reducers: 
    changeBanners(state,  payload ) 
      state.banners = payload
    ,
    changeRecommends(state,  payload ) 
      state.recommends = payload
    
  
)

export const  changeBanners, changeRecommends  = homeSlice.actions

export default homeSlice.reducer

不管是哪种方式, 都需要在页面的componentDidMount生命周期中, 通过派发异步的action发送网络请求

import React,  PureComponent  from 'react'
import  connect  from 'react-redux'
import  fetchHomeMultidataAction  from '../store/features/home'

export class About extends PureComponent 
  // 生命周期中, 调用映射的方法派发异步的action
  componentDidMount() 
    this.props.fetchHomeMultidata()
  

  render() 
    const  banners, recommends  = this.props

    return (
      <div>
        <h2>About</h2>
        <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.home.banners,
  recommends: state.home.recommends
)
// 派发异步的action
const mapDispatchToProps = (dispatch) => (
  fetchHomeMultidata() 
    dispatch(fetchHomeMultidataAction())
  
)

export default connect(mapStateToProps, mapDispatchToProps)(About)

Redux ToolKit:提交调度

【中文标题】Redux ToolKit:提交调度【英文标题】:Redux ToolKit: Submit a dispatch 【发布时间】:2020-06-11 12:00:13 【问题描述】:

您好,我正在尝试使用 redux 工具包,但我怀疑如何发送调度来更改减速器的状态

我的商店:

import  configureStore  from '@reduxjs/toolkit';

import rootReducer from './rootReducer';

const store = configureStore(
  reducer: rootReducer,
);

if (process.env.NODE_ENV === 'development' && module.hot) 
  module.hot.accept('./rootReducer', () => 
    const newRootReducer = require('./rootReducer').default;
    store.replaceReducer(newRootReducer);
  );


export default store;

我的根减速器:

import  combineReducers  from '@reduxjs/toolkit';
import  togglePopUp  from '../slices/popupMenu';
const rootReducer = combineReducers(
  togglePopUp: togglePopUp.reducer,
);

export default rootReducer;

我的切片:

import  createSlice  from '@reduxjs/toolkit';

const INITIAL_STATE = 
  popUpIsOpen: false,
;

const togglePopUp = createSlice(
  name: 'popUp',
  initialState: INITIAL_STATE,
  reducers: 
    toggle: (state, action) => 
      console.log(action);
    ,
  ,
);

export const  toggle  = togglePopUp.actions;
export  togglePopUp ;

我的 jsx:

  const dispatch = useDispatch();
  const  popUpIsOpen  = useSelector(RootState => RootState.togglePopUp);
            <p onClick=() => dispatch(toggle())>
              My Account
              <span>
                <FontAwesomeIcon
                  className="adjust"
                  icon=faAngleDown
                  size="xs"
                  fixedWidth
                  color="white"
                />
              </span>
            </p>

我基本上是想在点击时制作一个切换菜单,将状态更改为 false 或 true

其中 false:已关闭 / 真实:打开,

我正在关注 redux toolkiit 教程,但我不确定如何发送调度以及如何更改切片上弹出菜单的状态

【问题讨论】:

你是否有一个 Redux Provider 可以让你的商店围绕你的应用程序? 是的,一切正常我的 useSelector 正确,问题是我不知道如何在我的切片中更改我的 Toggle const 状态。 基本上我的初始值是:popUpIsOpen: false,即关闭菜单,当我发送dispatch时我想改变这个状态的值 【参考方案1】:

我解决了这个问题。

const togglePopUp = createSlice(
  name: 'popUp',
  initialState: INITIAL_STATE,
  reducers: 
    toggle: (state, action) => 
      state.popUpIsOpen: !state.popUpIsOpen
    ,
  ,
);

【讨论】:

以上是关于Redux工具包 - Redux Toolkit的异步操作(发送网络请求)的主要内容,如果未能解决你的问题,请参考以下文章

Redux-Toolkit createAsyncThunk with Typescript

WebStorm 中的 Redux-toolkit 操作参数

Redux Toolkit

如何使用 redux-toolkit 动态更改基本 URL?

react——Redux Toolkit

测试 createAsyncThunk Redux Toolkit Jest