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

React开发电影趋势页:从单对象JSON API批量存数据出错求助

问题分析与修复方案

核心问题

你的代码存在几个关键问题导致了异常结果:

  • 异步时序错误:调用getData后立刻执行trends.push(movie),此时API请求还没完成,movie还是初始的空对象,所以数组里全是空值。
  • 直接修改State:trends.push(movie)是直接修改原State数组,React无法识别这种变更,后续setTrends(trends)传递的是同一个数组引用,不会触发正确的重新渲染。
  • 闭包与重复更新:循环里多次调用setTrends,每次拿到的trends都是初始的空数组(闭包特性),多次push后会导致数组长度超出预期。
  • 单个State被覆盖:多个请求共享同一个movie State,后完成的请求会覆盖之前的结果,即使等待请求完成,最终也无法正确收集所有电影数据。

修复后的代码

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

function MovieTrends() {
  const [trends, setTrends] = useState([]);
  const trendsTitles = ["dune", "annette", "cendrillon", "mon frere", "athena", "footloose"];

  // 修改getData,让它返回请求结果,不再依赖单个movie state
  async function getData(title) {
    try {
      const response = await axios.get(`http://www.omdbapi.com/?apikey=[apikey]&t=${title}`);
      return response.data;
    } catch (error) {
      console.log(`获取电影${title}失败:`, error);
      return null; // 失败时返回null,避免影响整体结果
    }
  }

  useEffect(() => {
    async function fetchAllMovies() {
      // 使用Promise.all并行处理所有请求,等待全部完成
      const moviePromises = trendsTitles.map(title => getData(title));
      const movies = await Promise.all(moviePromises);
      // 过滤掉请求失败的null值,再更新state
      setTrends(movies.filter(movie => movie !== null));
    }

    fetchAllMovies();
  }, []);

  return (
    <div>
      {/* 这里渲染你的电影列表 */}
      {trends.map((movie, index) => (
        <div key={index}>
          <h3>{movie.Title}</h3>
          <p>{movie.Year}</p>
        </div>
      ))}
    </div>
  );
}

export default MovieTrends;

关键改动说明

  1. 让getData返回数据:不再用setMovie存储单个电影,而是直接返回请求结果,避免状态被覆盖。
  2. 用Promise.all处理并发请求:一次性发起所有请求,等待全部完成后再统一更新State,保证数据完整且只触发一次渲染。
  3. 避免直接修改State:通过生成新的电影数组来更新trends,符合React的State更新规范。
  4. 错误处理优化:请求失败时返回null,后续过滤掉无效数据,避免错误数据影响页面渲染。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 07:45:39