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

React中使用useEffect调用两个存在依赖关系的API失败如何解决?

错误原因排查

  • 状态初始值类型错误:randomid 初始值被设置为数组[],实际存储的是对象类型的接口返回数据,首次渲染时第二个useEffect触发,此时randomid.id为undefined,拼接进请求URL会生成非法请求路径。
  • 缺少请求前置校验:第二个useEffect没有判断randomid是否存在有效id就直接发起请求,会触发无效调用。
  • 数据类型不匹配风险:第一个接口请求的是trending/all/day,返回结果包含电影、剧集两类内容,直接拼接进/movie/路径请求时,如果拿到的是剧集类数据会返回404错误。
  • 缺失错误处理逻辑:两个axios请求都没有catch捕获异常,接口报错时容易导致页面崩溃。
  • 状态声明缺失:代码中未声明key对应的状态,直接调用setkey会抛出未定义错误。

优化实现方案

方案1:保留双useEffect逻辑的修复版本

import { useState, useEffect } from 'react'
import axios from 'axios'

const YourComponent = () => {
  // 初始值设为null标记未加载状态
  const [randomid, setRandomId] = useState(null)
  const [key, setKey] = useState(null)
  const API_KEY = '替换为你的实际api_key'

  // 获取趋势列表
  useEffect(() => {
    axios.get(`https://api.themoviedb.org/3/trending/all/day?api_key=${API_KEY}`)
      .then((response) => {
        // 过滤仅保留电影类型,避免后续接口报错
        const movieList = response.data.results.filter(item => item.media_type === 'movie')
        if (movieList.length) {
          setRandomId(movieList[0])
        }
      })
      .catch(err => console.error('获取趋势列表失败:', err))
  }, [API_KEY])

  // 拿到id后请求视频数据
  useEffect(() => {
    // 无有效id时直接返回,不发起请求
    if (!randomid?.id) return
    axios.get(`https://api.themoviedb.org/3/movie/${randomid.id}/videos?api_key=${API_KEY}&language=en-US`)
      .then((response) => {
        if (response.data.results.length) {
          setKey(response.data.results[0])
        }
      })
      .catch(err => console.error('获取视频数据失败:', err))
  }, [randomid, API_KEY])

  return <div>组件渲染逻辑</div>
}

方案2:更推荐的单useEffect链式调用版本(减少冗余依赖)

import { useState, useEffect } from 'react'
import axios from 'axios'

const YourComponent = () => {
  const [key, setKey] = useState(null)
  const API_KEY = '替换为你的实际api_key'

  useEffect(() => {
    const fetchData = async () => {
      try {
        // 第一步:获取趋势列表
        const trendRes = await axios.get(`https://api.themoviedb.org/3/trending/all/day?api_key=${API_KEY}`)
        const movieList = trendRes.data.results.filter(item => item.media_type === 'movie')
        if (!movieList.length) return
        // 第二步:直接用返回的id请求视频数据,无需额外存id状态
        const videoRes = await axios.get(`https://api.themoviedb.org/3/movie/${movieList[0].id}/videos?api_key=${API_KEY}&language=en-US`)
        if (videoRes.data.results.length) {
          setKey(videoRes.data.results[0])
        }
      } catch (err) {
        console.error('请求失败:', err)
      }
    }
    fetchData()
  }, [API_KEY])

  return <div>组件渲染逻辑</div>
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 09:54:00