You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Redux-Toolkit自定义selectId?解决Valorant API数据加载异常

问题解决:Redux Entity Adapter警告与特工列表显示不全

核心问题分析

你遇到的两个问题直接关联:

  • Redux警告the entity passed from selectId returned undefined:createEntityAdapter默认用id作为实体唯一标识,但Valorant API返回的特工数据以uuid作为唯一ID,导致适配器无法识别有效标识。
  • 仅显示1个特工:所有实体的标识被判定为undefined,每次调用addOne都会覆盖同一个实体位置,最终只保留最后一条数据。

具体修复步骤

1. 自定义Entity Adapter的selectId函数

创建适配器时,明确指定使用uuid作为实体唯一标识:

const valorantAdapter = createEntityAdapter({
  selectId: (agent) => agent.uuid // 替换默认id字段为uuid
});

2. 优化数据批量添加逻辑

原代码中用forEach循环调用addOne可以替换为addMany,一次性添加所有特工数据,代码更简洁且性能更优:

.addCase(fetchValorants.fulfilled, (state, action) => {
  state.status = "succeeded";
  // 替换forEach循环为addMany批量操作
  valorantAdapter.addMany(state, action.payload);
})

修改后的完整Slice代码

import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import { createEntityAdapter } from "@reduxjs/toolkit";
import axios from "axios";

// 配置自定义selectId的Entity Adapter
const valorantAdapter = createEntityAdapter({
  selectId: (agent) => agent.uuid
});

const initialState = valorantAdapter.getInitialState({
  status: "idle",
  error: "" as any,
});

export const fetchValorants = createAsyncThunk(
  "valorants/fetchValorants",
  async () => {
    const response = await axios
      .get("https://valorant-api.com/v1/agents")
      .then((response) => response.data.data)
      .then((agents) => {
        return Promise.all(
          agents.map((agent: any) =>
            axios.get(`https://valorant-api.com/v1/agents/${agent.uuid}`)
          )
        );
      })
      .then((agentDetails) => {
        return agentDetails.map((response) => response.data.data);
      });

    return response;
  }
);

const valorantsSlice = createSlice({
  name: "valorants",
  initialState,
  reducers: {},
  extraReducers(builder) {
    builder
      .addCase(fetchValorants.pending, (state, action) => {
        state.status = "loading";
      })
      .addCase(fetchValorants.fulfilled, (state, action) => {
        state.status = "succeeded";
        // 使用addMany批量添加数据
        valorantAdapter.addMany(state, action.payload);
      })
      .addCase(fetchValorants.rejected, (state, action) => {
        state.status = "failed";
        state.error = action.error.message;
      });
  },
});

export default valorantsSlice.reducer;
export const {
  selectAll: selectAllValorants,
  selectById: selectValorantByUuid,
  selectIds: selectValorantUuids,
} = valorantAdapter.getSelectors((state: any) => state.valorants) as any;

额外优化建议

  • 异步逻辑可简化:第一次调用/v1/agents时已经返回了所有特工的完整数据,无需再逐个请求详情接口,直接返回response.data.data即可减少不必要的网络请求。
  • 完善类型定义:建议给agent编写TypeScript接口,避免使用any类型,提升代码健壮性。

内容的提问来源于stack exchange,提问作者Muhammad Yafi A

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 04:09:57