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

React-Redux问题:dispatch无法将API数据存入state

问题描述

刚接触Redux,正在项目中练习使用。API调用已成功获取数据并保存到data(第27行已打印),但第28行打印的Redux state中的AnimeList.data却是空数组,请问这是什么原因?


AnimeList.js

import React, { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';

import { useGetTrendingAnimeListQuery } from '../../services/animeApi';
import { addData } from './AnimeListSlice';

import AnimeCard from '../AnimeCard/AnimeCard';
import AnimeSelector from '../AnimeSelector/AnimeSelector';

import { Spin } from 'antd';

import './AnimeList.css';

const AnimeList = () => {

  const AnimeList = useSelector((state) => state.AnimeList.data);
  const dispatch = useDispatch();
  
  const { data, isFetching } = useGetTrendingAnimeListQuery();

  useEffect(() => {
    if (!isFetching) {
      dispatch(addData(data));
    }
  }, []);

  console.log(data);
  console.log(AnimeList);

  const loadingCards = [1, 2, 3, 4, 5];

  return (
    <div className='container'>
      {!isFetching
        ? <div className="wrapper">
            <AnimeSelector />
            <div className='anime-list-wrapper'>
              {AnimeList.map((anime) => (
                <AnimeCard anime={anime} key={anime.id} />
              ))}
            </div>
          </div>
        :
        <div className='wrapper'>
          <div className='anime-list-wrapper'>
            {loadingCards.map(() => (
              <div className='loading-card'>
                <Spin />
              </div>
            ))}
          </div>
        </div>
      }
    </div>
  )
}

export default AnimeList;

AnimeListSlice.js

import { createSlice } from "@reduxjs/toolkit";

const initialState = {
    data: []
};

export const AnimeListSlice = createSlice({
    name: 'AnimeList',
    initialState,
    reducers: {
        addData: (state, action) => {
            state.data = action.payload;
        },
    }
});

export const { addData } = AnimeListSlice.actions;

export default AnimeListSlice.reducer;

animeApi.js

import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";

const animeApiHeaders = {
    "Accept": "application/vnd.api+json",
    "Content-Type": "application/vnd.api+json",
};

const baseUrl = 'https://kitsu.io/api/edge';

const createRequest = (url) => ({ url, headers: animeApiHeaders });

export const animeApi = createApi({
    reducerPath: 'animeApi',
    baseQuery: fetchBaseQuery({ baseUrl }),
    endpoints: (builder) => ({
        getTrendingAnimeList: builder.query({
            query: () => createRequest('/trending/anime?limit=20'),
        }),
        getAllAnimeList: builder.query({
            query: () => createRequest('/anime?limit=20'),
        }),
    })
});

export const { useGetTrendingAnimeListQuery, useGetAllAnimeList } = animeApi;

问题原因与修复方案

核心原因

你的useEffect依赖项是空数组,导致它只会在组件首次挂载时执行一次。此时API请求还未完成:isFetching仍为true,data还是初始的undefined,所以不会触发dispatch(addData(data)),Redux state保持初始的空数组状态。

后续API请求完成后,data和isFetching发生变化,但useEffect因为没有监听这两个依赖项,不会重新执行,所以数据永远不会被存入Redux。

另外,Kitsu API的响应结构是外层包含data字段的对象(比如{ data: [...], meta: ... }),你直接把整个响应对象传给addData的话,最终state.AnimeList.data会是这个对象,而非实际的动漫数组,后续渲染时AnimeList.map会报错。

修复步骤

  1. 修正useEffect依赖项:将data和isFetching加入依赖数组,确保状态变化时重新执行dispatch:
useEffect(() => {
  // 同时判断data是否存在,避免初始时传入undefined
  if (!isFetching && data) {
    dispatch(addData(data.data)); // 取响应中的实际数据数组
  }
}, [data, isFetching, dispatch]); // 添加依赖
  1. 正确提取API数据:在dispatch时传入data.data,拿到实际的动漫列表数组。

  2. 可选优化:其实RTK Query本身已经把数据缓存到Redux中,你可以直接通过useGetTrendingAnimeListQuery的返回值获取数据,不需要额外手动存入自己的slice,这样能减少冗余代码。比如直接用data?.data来渲染:

// 去掉useSelector和useEffect相关代码
return (
  <div className='container'>
    {!isFetching
      ? <div className="wrapper">
          <AnimeSelector />
          <div className='anime-list-wrapper'>
            {data?.data.map((anime) => (
              <AnimeCard anime={anime} key={anime.id} />
            ))}
          </div>
        </div>
      : // 加载状态...
    }
  </div>
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 21:15:35