使用React Redux实现异步请求

完整代码channelStore.js

javascript 复制代码
import { createSlice } from "@reduxjs/toolkit";
import axios from "axios"

const channelStore = createSlice({
    name: 'channel',
    initialState: {
        channelList: []
    },
    reducers: {
        setChannels (state, action){
            state.channelList = action.payload
        }
    }
})

const { setChannels } = channelStore.actions

const fetchChannelList = () => {
    return async(dispatch) => {
        const res = await axios.get('http://geek.itheima.net/v1_0/channels')
        dispatch(setChannels(res.data.data.channels))
    }
}

export { fetchChannelList }

const channelReducer = channelStore.reducer

export default channelReducer

这段代码展示了一个使用 Redux Toolkit 和 axios 实现的异步请求示例,主要用于从 API 获取频道列表并存储在 Redux 的状态中。以下是代码的详细解释:


1. 导入依赖

javascript 复制代码
import { createSlice } from "@reduxjs/toolkit";
import axios from "axios";
  • createSlice :
    • Redux Toolkit 提供的工具,用于简化创建 Redux 的 action 和 reducer。
    • 它会自动生成对应的 action 和 reducer,减少样板代码。
  • axios :
    • HTTP 客户端,用于发送异步请求(如 GET, POST 等)。
    • 在这里用来从指定的 API 获取频道数据。

2. 定义 channelStore

javascript 复制代码
const channelStore = createSlice({
    name: 'channel',
    initialState: {
        channelList: []
    },
    reducers: {
        setChannels (state, action){
            state.channelList = action.payload
        }
    }
});
参数解释
  • name :模块名称,定义在 Redux 中的命名空间(state.channel)。
  • initialState :定义初始状态。
    • channelList:一个空数组,用于存储频道列表。
  • reducers :
    • 定义同步的状态更新逻辑。
    • 每个 reducer 函数接收两个参数:
      1. state:当前状态。
      2. action :包含 type 和 payload(数据负载)。
setChannels 函数
  • 作用 :更新 channelList 的状态。
  • 逻辑 :将 action.payload 的内容赋值给 state.channelList。

3. 提取 setChannels 动作

javascript 复制代码
const { setChannels } = channelStore.actions;
  • 自动生成的 setChannels 动作。
  • 可用于触发 setChannels reducer,更新 channelList。

4. 定义异步操作 fetchChannelList

javascript 复制代码
const fetchChannelList = () => {
    return async(dispatch) => {
        const res = await axios.get('http://geek.itheima.net/v1_0/channels');
        dispatch(setChannels(res.data.data.channels));
    };
};
作用
  • 目的:从 API 获取频道数据并存储到 Redux 状态中。
  • 逻辑 :
    1. 定义一个返回异步函数的 action:

      • 接收 dispatch 参数,用于触发同步 action。
    2. 使用 axios.get 向指定的 URL 发送 GET 请求。

    3. 提取返回数据中的 channels 列表:

      javascript 复制代码
      res.data.data.channels
    4. 调用 dispatch(setChannels(...)):

      • 将提取到的 channels 列表传递给 setChannels 动作。
      • 触发 setChannels reducer,更新 channelList 的状态。
注意
  • 这是一个 Redux 异步 action(也称为 Thunk)。
  • dispatch 是由 Redux 提供的,用于触发同步或异步的状态更新。

5. 导出和定义 channelReducer

javascript 复制代码
const channelReducer = channelStore.reducer;
export default channelReducer;
  • channelReducer :
    • Redux Store 的一部分,用于处理 channel 模块的状态更新。
    • 通过 createSlice 自动生成的 reducer 函数。
  • 导出 channelReducer :
    • 用于在 Redux Store 中注册为 channel 状态的处理逻辑。

6. 导出 fetchChannelList

javascript 复制代码
export { fetchChannelList };
  • 导出异步函数 fetchChannelList,以便组件中使用。
  • 组件中可以通过 dispatch(fetchChannelList()) 触发异步请求并更新状态。

7. 代码工作流程

  1. 初始化状态:

    • Redux 的初始状态为:

      javascript 复制代码
      {
        channelList: []
      }
  2. 触发异步请求:

    • 组件调用 dispatch(fetchChannelList())。
    • fetchChannelList 异步函数:
      1. 使用 axios 向 API 发送请求。
      2. 提取返回的频道列表。
      3. 调用 dispatch(setChannels(...)) 更新状态。
  3. 更新状态:

    • setChannels 动作触发后,channelReducer 更新状态:

      javascript 复制代码
      state.channelList = action.payload;
  4. 状态同步到组件:

    • Redux 状态更新后,连接 Redux 的组件会自动重新渲染,展示最新数据。

8. 适用场景

  • 用于管理从后端获取的动态数据,例如:
    • 频道列表。
    • 用户信息。
    • 产品列表。

9. 扩展建议

  • 错误处理 :

    • 在 fetchChannelList 中添加错误捕获机制:

      javascript 复制代码
      try {
          const res = await axios.get('...');
          dispatch(setChannels(res.data.data.channels));
      } catch (error) {
          console.error("Failed to fetch channels:", error);
      }
  • 加载状态 :

    • 添加 isLoading 和 error 状态,表示数据加载的过程和结果。
  • 测试 :

    • 编写单元测试,验证 setChannels 和 fetchChannelList 的逻辑。

总结

这段代码通过 Redux Toolkit 和 axios 实现了一个完整的状态管理流程,包括异步获取频道列表并将其存储在 Redux 中的逻辑。它是一个模块化、可扩展的 Redux 状态管理示例。

相关推荐
中文呀1 小时前
三维 GIS 离线缓存实战:逆向 CesiumOfflineCache,并亲手为它补上"自动更新"能力
前端
前进前进前进2 小时前
TRAE 全链路实战:做了一个警示牌一键生成器:纯 Canvas、单文件、零依赖
前端
小万7423 小时前
God‘s Eye View 深度解析:15 路公开信号 + CesiumJS 的浏览器级 OSINT 控制台,60 帧渲染的“真实间谍卫星模拟器”
前端
IT星宿3 小时前
浏览器标签页全是一个图标:我用名字哈希生成 favicon,让每个项目都有身份标识
前端
OpsEye3 小时前
大模型账单对账难:不同厂商 Token 统计口径差异怎么处理
javascript·ai编程
全栈项目管理程序猿3 小时前
ArcGIS JS 基础教程(32):体元系列 - VoxelSlice 体元切片
前端·javascript
结局无敌5 小时前
React Native for OpenHarmony 实战:三方库 react-native-modal-dialog 的鸿蒙化适配指南
深度学习·算法·react native·react.js·harmonyos
拖孩6 小时前
AI 帮我写的小程序「厨菜记」上线满月了,挣了两百块!!!
前端·后端·微信小程序
用户360055579006 小时前
Kestrel_VLLM - 13 · 为什么排除 MoE FFN Tiling 与 Tensor Core
前端
Hilaku6 小时前
AI 流式输出都用 SSE,什么时候必须换 WebSocket?
前端·javascript·程序员