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

React.js中TMDB图片API 404(undefined)错误排查与解决求助

解决Redux-Toolkit影视详情页图片404错误

问题现象

页面加载时出现图片请求404错误:undefined (GET https://image.tmdb.org/t/p/w500/undefined 404),错误源于图片URL拼接逻辑:https://image.tmdb.org/t/p/w500/${movieDetails?.poster_path},当poster_path为undefined或null时,会生成无效URL。

核心原因

  1. 数据加载时机不匹配:加载状态标记为false时,对应详情数据可能未正确初始化,或接口返回的poster_path本身为null。
  2. 无效请求触发:子组件同时发起电影和剧集数据请求,导致无关状态干扰渲染逻辑。
  3. Redux状态管理不完善:请求失败时未重置加载状态,初始状态为空对象,未处理接口返回空值的情况。

解决方案

1. 增加图片URL兜底处理

当poster_path不存在时,使用占位图或跳过图片渲染,避免无效请求:
修改DetailsView.js中的图片渲染部分:

<div className="details-view-poster">
  {/* 只有当poster_path存在时才渲染图片 */}
  {(movieId ? movieDetails?.poster_path : tvshowDetails?.poster_path) && (
    <img
      src={
        movieId
          ? `https://image.tmdb.org/t/p/w500/${movieDetails.poster_path}`
          : `https://image.tmdb.org/t/p/w500/${tvshowDetails.poster_path}`
      }
      alt="poster"
    />
  )}
</div>

如果需要占位图,可替换为:

<img
  src={
    movieId
      ? movieDetails?.poster_path
        ? `https://image.tmdb.org/t/p/w500/${movieDetails.poster_path}`
        : '/path/to/your/placeholder-image.jpg'
      : tvshowDetails?.poster_path
        ? `https://image.tmdb.org/t/p/w500/${tvshowDetails.poster_path}`
        : '/path/to/your/placeholder-image.jpg'
  }
  alt="poster"
/>

2. 修正数据加载逻辑

在DetailViewInfo.js中,根据路由参数仅加载对应类型的数据,避免无效请求:

useEffect(() =>{
  if(movieId) {
    dispatch(fetchMovieId(movieId));
  } else if(tvshowId) {
    dispatch(fetchTvshow(tvshowId));
  }
}, [movieId, tvshowId, dispatch])

3. 完善Redux切片状态管理

在movieSlice.js中,确保请求完成(成功/失败)时正确更新加载状态:

// fetchMovieId中修改catch块
catch (error) {
  dispatch(setError(error));
  dispatch(setPending(false)); // 请求失败关闭加载状态
  console.log(error);
}

// 修改setSuccess reducer
setSuccess(state, action) {
  state.loadingMovie = false; // 请求成功关闭加载状态
  state.movieDetails = action.payload;
}

同理,tvshowSlice需做相同修改,保证loadingTvshow状态正确更新。

4. 优化加载状态判断逻辑

在DetailsView.js中,仅判断当前类型的加载状态,避免逻辑混乱:

const DetailView = () => {
  const movieData = useSelector((state) => state.movies)
  const tvshowData = useSelector((state) => state.tvshow)
  const { movieId, tvshowId } = useParams(); // 同时解构tvshowId
  const { movieDetails, loadingMovie} = movieData;
  const {tvshowDetails, loadingTvshow} = tvshowData;

  // 根据当前类型判断加载状态
  const isLoading = movieId ? loadingMovie : loadingTvshow;

  return (
    <div>
      <Navbar/>
      <div style={{marginTop: "100px"}} className="detail-view-wrapper">
        {isLoading ?(
          <BounceLoader css={override} size={40}/>
        ):(
          <div className="details-view-poster">
            {/* 图片渲染逻辑 */}
          </div>
        )}
      </div>
      <DetailViewInfo/>
      <h1>DetailsView </h1>
      <FnavBar/>
    </div>
  )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 22:25:24