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

使用Redux Toolkit调用TMDB API获取全类型电影遇单类型返回问题求助

问题:Redux Toolkit调用TMDB API获取全分类电影的问题

我正在尝试用Redux Toolkit调用TMDB API,获取所有电影类型下的全部电影。我写了循环发起API请求,原本想把所有电影都存入Movies数组,但现在循环只能返回第一个类型的电影。我的目标是让dataMovieGenres收集到所有电影数据,在extraReducers里处理后,能遍历展示所有分类的电影。另外我需要一种不用push(避免副作用)的方式,把Axios返回的所有数据存入数组并返回。

当前代码

初始状态

const initialState = {
  Most_Popular: [], // 首页展示的热门电影列表
  top_rated: [], // 首页展示的高分电影列表
  Movies: [], // 所有电影列表
  Movie: {}, // 当前选中的电影
  isLoading: true, // 检查页面是否加载中
  isError: false,
};

获取分类电影的异步Thunk

export const getMoviesGenres = createAsyncThunk(
  "getMoviesGenres",
  async (_, thunkAPI) => {
    try {
      const api = `api_key=${process.env.REACT_APP_KEY_API}`;
      const data = await getJSON.get(`genre/movie/list?${api}`); // 获取所有类型ID

      for (let i = 0; i <= data.data.genres.length; i++) {
        if (!data.data.genres[i]) return; // 守卫语句
        const { id, name } = data.data.genres[i];

        const dataMovieGenres = [
          await getJSON.get(`discover/movie?${api}&with_genres=${id}`)
        ];
        return dataMovieGenres;
      }
    } catch (error) {
      return thunkAPI.rejectWithValue(error);
    }
  }
);

Reducer处理逻辑

// 获取分类电影
builder
  .addCase(getMoviesGenres.pending, (state) => {
    state.isLoading = true;
    state.isError = false;
  })
  .addCase(getMoviesGenres.fulfilled, (state, { payload }) => {
    console.log(payload);
    // state.Movies = payload.data.results;
    state.isLoading = false;
    state.isError = false;
  })
  .addCase(getMoviesGenres.rejected, (state, { payload }) => {
    state.isLoading = false;
    state.isError = false;
    toast.error(payload.message);
  });

问题原因

  1. 循环内的return dataMovieGenres会直接终止函数,导致仅执行第一次循环就返回第一个分类的数据。
  2. 循环条件i <= data.data.genres.length会触发最后一次循环时data.data.genres[i]为undefined,触发守卫语句直接return。

解决方法

使用map生成所有请求的Promise,再配合Promise.all并行处理所有请求,既无副作用又能收集全部数据:

修改后的异步Thunk

export const getMoviesGenres = createAsyncThunk(
  "getMoviesGenres",
  async (_, thunkAPI) => {
    try {
      const api = `api_key=${process.env.REACT_APP_KEY_API}`;
      const genresRes = await getJSON.get(`genre/movie/list?${api}`);
      const genres = genresRes.data.genres;

      // 用map生成请求Promise数组,Promise.all等待全部完成
      const allMoviesData = await Promise.all(
        genres.map(async ({ id, name }) => {
          const movieRes = await getJSON.get(`discover/movie?${api}&with_genres=${id}`);
          // 返回包含分类名称和对应电影的对象,方便后续展示
          return {
            genreName: name,
            movies: movieRes.data.results
          };
        })
      );

      return allMoviesData;
    } catch (error) {
      return thunkAPI.rejectWithValue(error);
    }
  }
);

修改后的Reducer处理

builder
  .addCase(getMoviesGenres.pending, (state) => {
    state.isLoading = true;
    state.isError = false;
  })
  .addCase(getMoviesGenres.fulfilled, (state, { payload }) => {
    // payload是包含所有分类及对应电影的数组,直接赋值
    state.Movies = payload;
    state.isLoading = false;
    state.isError = false;
  })
  .addCase(getMoviesGenres.rejected, (state, { payload }) => {
    state.isLoading = false;
    state.isError = true; // 标记错误状态
    toast.error(payload.message);
  });

说明

  • Promise.all并行处理请求,比串行循环效率更高。
  • 返回的每个对象包含分类名称和对应电影列表,后续展示时可直接遍历Movies数组按分类渲染。
  • 通过map生成新数组,完全避免了push带来的副作用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 23:17:11