调用TMDB API获取数据后调用setState触发无限请求如何解决?
问题根因
- 你的请求逻辑直接写在了组件函数的顶层,React 组件每次渲染都会执行全部顶层代码。你调用
setFavorites更新状态后会触发组件重新渲染,重新渲染又会从头执行请求逻辑,请求成功后再次调用setFavorites,就形成了「渲染→发请求→更新状态→重新渲染」的无限循环。 - 额外代码问题:你在
forEach遍历返回结果时每次都调用setFavorites,属于无意义的重复更新,应该等所有结果处理完成后再统一更新状态。
修复方案
将请求逻辑包裹在useEffect钩子中,指定依赖项控制请求触发时机,同时修正结果处理逻辑:
import { useState, useEffect } from 'react' // ... 组件内部其他逻辑 const [favorites, setFavorites] = useState([]) useEffect(() => { // 避免movieId为空时发无效请求 if (!movieId?.length) return let moviesToReturn = [] const requests = movieId.map(id => { return new Promise((resolve, reject) => { request({ url: `https://api.themoviedb.org/3/movie/${id.movieId}?api_key=${movieApikey}`, method: 'GET' }, (err, res, body) => { if (err) return reject(err) resolve(body) }) }) }) Promise.all(requests).then((body) => { body.forEach(res => { if (res) moviesToReturn.push(JSON.parse(res)) }) // 所有数据处理完成后统一更新状态,只调用一次 console.log(moviesToReturn, 'movies to return') setFavorites(moviesToReturn) }).catch(err => console.log(err)) // 依赖项只填movieId,只有当保存的id列表变化时才重新发起请求 }, [movieId])
内容的提问来源于stack exchange,提问作者Dylan Rowe
相关产品推荐
相关产品推荐

