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

Redux Toolkit中使用axios获取API数据报错如何解决

问题根因

你的代码存在3个直接触发报错的问题:

  • 异步逻辑写法完全错误:axios.get()返回的是Promise异步对象,你直接把这个对象存到了初始state里,根本没有拿到接口返回的实际数组数据
  • Redux的reducer和state初始化逻辑必须是同步纯函数,Redux Toolkit(以下简称RTK)中所有异步请求需要用官方内置的createAsyncThunk处理,不能直接在slice外层裸写请求塞值
  • useSelector取值路径错误:你定义的slice初始state是{value: xxx}结构,本身是个对象不是数组,直接对对象调用.map()方法必然触发「xxx.map is not a function」的类型错误,和你运行时的报错完全吻合
  • 额外拼写问题:你的slice文件名、action名里的compnay是拼写错误,正确拼写是company,虽然不直接触发报错,但很容易后续引发导入路径类的bug
修正后代码

1. 重写slice文件(修正文件名:companyList.js)

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

// 定义异步请求方法
export const fetchCompanies = createAsyncThunk(
  'companyList/fetchCompanies',
  async () => {
    const res = await axios.get('https://mocki.io/v1/d4867d8b-b5d5-4a48-a4ab-79131b5809b8');
    return res.data;
  }
);

const companySlice = createSlice({
  name: 'companyList',
  initialState: {
    value: [],
    loading: false,
    error: null
  },
  reducers: {
    // 修正之前的拼写错误
    addCompany: (state, action) => {
      state.value.push(action.payload);
    }
  },
  // 监听异步请求的三个状态,更新state
  extraReducers: (builder) => {
    builder
      .addCase(fetchCompanies.pending, (state) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(fetchCompanies.fulfilled, (state, action) => {
        state.loading = false;
        state.value = action.payload;
      })
      .addCase(fetchCompanies.rejected, (state, action) => {
        state.loading = false;
        state.error = action.error.message;
      });
  }
});

export const { addCompany } = companySlice.actions;
export default companySlice.reducer;

2. 修正App.js

import { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { fetchCompanies } from './features/companySlice/companyList';

function App() {
  const dispatch = useDispatch();
  // 正确取到state里的数组、加载状态、错误信息
  const { value: companies, loading, error } = useSelector(state => state.companyList);

  // 组件挂载时触发请求
  useEffect(() => {
    dispatch(fetchCompanies());
  }, [dispatch]);

  // 处理加载和报错场景
  if (loading) return <div className="App">数据加载中...</div>;
  if (error) return <div className="App">请求失败:{error}</div>;

  return (
    <div className="App">
      <header className="App-header">
        {companies.map(company => (
          // 循环项必须加唯一key
          <h1 key={company.name}>{company.name}</h1>
        ))}
        <h1>hello</h1>
      </header>
    </div>
  );
}

export default App;

3. 修正store.js的导入路径

import { configureStore } from '@reduxjs/toolkit';
// 修正之前的文件名拼写错误
import companyReducer from './features/companySlice/companyList';

export const store = configureStore({
  reducer: {
    companyList: companyReducer
  }
});
核心注意事项
  • Redux的state必须是可序列化的普通数据,绝对不能把Promise、函数这类特殊对象直接存到state里
  • RTK中不要在reducer、slice初始化逻辑里写异步代码,异步请求统一用createAsyncThunk,如果是接口类场景多也可以直接用RTK Query,不用手写thunk
  • 写useSelector的时候一定要对应你自己定义的state结构,不要拿错数据层级
  • 数组循环渲染必须给每一项加唯一的key属性,避免React渲染警告和异常

内容的提问来源于stack exchange,提问作者Ali Mozaffari

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 00:27:19