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

React+Redux Toolkit调用TMDB API详情页数据返回Undefined求助

React电影应用详情页API数据返回Undefined问题修复

问题现状

使用React.js开发电影Web应用,通过TMDB API获取列表数据正常,但点击电影卡片跳转至详情页后,调用API返回Undefined,控制台显示数据为Undefined,采用Redux Toolkit进行状态管理。

核心问题原因

  1. TMDB接口返回结构处理错误:TMDB的/movie/{id}单电影详情接口返回的是单个电影对象,而非列表接口那样包含results数组的结构,但异步action中错误地返回了response.data.results,导致获取不到有效数据。
  2. 组件依赖项缺失:Detail组件的useEffect未将路由参数id加入依赖数组,路由参数变化时无法重新触发数据请求。
  3. 异步操作日志时机错误:在useEffect中直接打印entity,此时异步请求尚未完成,拿到的是初始状态的空对象。

修复步骤

1. 修正异步Action的返回值

修改action.js中的fetchMovie函数,直接返回接口返回的单个电影对象:

import { createAsyncThunk } from "@reduxjs/toolkit";
import { movieList } from "../../service/api/api";

export const fetchMovieAll = createAsyncThunk('movie/fetchMovieAll', async() => {
    try {
        const api = `api_key=${import.meta.env.VITE_TMDB_KEY}`
        const response = await movieList.get(`discover/movie?${api}`)
        return response.data.results
    } catch (error) {
        return error
    }
})

export const fetchMovie = createAsyncThunk('movie/fetchMovie', async(id) => {
    try {
        const response = await movieList.get(`/movie/${id}?api_key=${import.meta.env.VITE_TMDB_KEY}`)
        // 单电影接口返回单个对象,无results字段
        return response.data
    } catch (error) {
        return error
    }
})

2. 完善Detail组件的依赖与日志逻辑

修改Detail.jsx,补充依赖数组并调整日志时机:

import React, { useEffect } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { useParams } from 'react-router-dom'
import { fetchMovie } from '../../manage/action'

function Detail() {
    const {id} = useParams()
    const dispatch = useDispatch()
    const {entity, loading} = useSelector((state) => state.movieDb)

    const fetchDataMovie = (movieId) => {
        dispatch(fetchMovie(movieId))
    }

    // 路由id变化时重新请求数据
    useEffect(() => {
        fetchDataMovie(id)
    }, [id, dispatch])

    // 监听entity变化后再打印
    useEffect(() => {
        console.log(entity)
    }, [entity])

    return (
        <>
            {loading ? <div>加载中...</div> : (
                <div>
                    <h1>{entity.title || '电影详情'}</h1>
                    {/* 可添加更多详情字段展示,例如海报、简介等 */}
                </div>
            )}
        </>
    )
}

export default Detail

3. 修正Slice中的错误状态逻辑

修改slice.js中请求失败时的loading状态(原代码错误设置为true):

import {createSlice} from '@reduxjs/toolkit'
import * as movieAction from '../action'

const movieDb = createSlice({
    name: 'movieDb',
    initialState: {
        loading: false,
        data: [],
        entity: {
            id: null,
            title: '',
            release_date: '',
            popularity: '',
            poster_path: '',
            overview: '',
            vote_average: '',
            backdrop_path: ''
        },
        error: null,
    },
    extraReducers: (builder) => 
        builder.addCase(movieAction.fetchMovieAll.pending, (state) => {
            state.loading = true
        })
        .addCase(movieAction.fetchMovieAll.fulfilled, (state, action) => {
            state.loading = false
            state.data = action.payload
        })
        .addCase(movieAction.fetchMovieAll.rejected, (state, action) => {
            state.loading = false
            state.error = action.payload
        })

        .addCase(movieAction.fetchMovie.pending, (state) => {
            state.loading = true
        })
        .addCase(movieAction.fetchMovie.fulfilled, (state, action) => {
            state.loading = false
            state.entity = action.payload
        })
        .addCase(movieAction.fetchMovie.rejected, (state, action) => {
            state.loading = false
            state.error = action.payload
        })
})

export default movieDb.reducer;

额外优化建议

  • 在CardMovie组件的useEffect中添加dispatch作为依赖,避免潜在的陈旧闭包问题:
useEffect(() => {
    fetchDataMovie()
}, [dispatch])
  • 可以根据loading状态添加加载动画,提升用户体验。

内容的提问来源于stack exchange,提问作者Hovi Sohibul Wafa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 23:12:55