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

React收藏电影组件map函数报错问题排查求助

问题:收藏电影组件map函数失效及API数据获取异常

错误信息

错误1

favorite.jsx:32 Uncaught TypeError: Cannot read properties of undefined (reading 'map')
    at Favorite (favorite.jsx:32:1)
    at renderWithHooks (react-dom.development.js:16305:1)
    at updateFunctionComponent (react-dom.development.js:19588:1)
    at beginWork (react-dom.development.js:21601:1)
    at HTMLUnknownElement.callCallback (react-dom.development.js:4164:1)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:1)
    at invokeGuardedCallback (react-dom.development.js:4277:1)
    at beginWork$1 (react-dom.development.js:27451:1)
    at performUnitOfWork (react-dom.development.js:26557:1)
    at workLoopSync (react-dom.development.js:26466:1)

错误2

favorite.jsx:32 Uncaught TypeError: movies.map is not a function
    at Favorite (favorite.jsx:32:1)
    at renderWithHooks (react-dom.development.js:16305:1)
    at updateFunctionComponent (react-dom.development.js:19588:1)
    at beginWork (react-dom.development.js:21601:1)
    at HTMLUnknownElement.callCallback (react-dom.development.js:4164:1)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:1)
    at invokeGuardedCallback (react-dom.development.js:4277:1)
    at beginWork$1 (react-dom.development.js:27451:1)
    at performUnitOfWork (react-dom.development.js:26557:1)
    at workLoopSync (react-dom.development.js:26466:1)

相关代码

Favorite组件核心代码

import { getAllFavorite } from "../../service/favServics";
import { useState, useEffect } from "react";
import PageHeader from "../common/pageHeader";
import FavoriteChiled from "./favoritechild";
function Favorite() {
  const [favorite, setFavorite] = useState([]);
  const [movies, setMovies] = useState([]);
  const [data, setData] = useState([]);
  async function getAll() {
    const { data } = await getAllFavorite();
    setFavorite(data);
    for (let i = 0; i < data.length; i++) {
      const url = `http://www.omdbapi.com/?s=${data[i]}&apikey=aea06659`;
      const response = await fetch(url);
      const responseJson = await response.json();
      const obj = responseJson.Search[0];
      if (responseJson.Search) {
        setMovies(obj.Title);
      }
    }
  }
  useEffect(() => {
    getAll(favorite);
  }, []);

Favorite组件返回部分

<div className="row">
  {movies.map((movie) => (
    <FavoriteChiled movie={movie} />
  ))}
</div>

子组件FavoriteChiled代码

function FavoriteChiled(props) {
  let { movies } = props;
  return (
    <>
      <div key={movies.imdbID} className="image-container d-flex justify-content-start m-3">
        <img src={movies.Poster} alt="movie"></img>
      </div>
    </>
  );
}

问题原因

  1. 状态类型错误:movies初始为数组,但循环中用setMovies(obj.Title)将其赋值为字符串,导致后续调用map时报错(字符串没有map方法)。
  2. 状态更新逻辑错误:循环中多次调用setMovies会覆盖之前的状态,无法累加电影数据。
  3. Props不匹配:父组件传递的props是movie,子组件解构的是movies,导致子组件无法获取正确数据。
  4. API请求未做异常处理:如果OMDb API返回的responseJson.Search为空,直接访问responseJson.Search[0]会导致undefined错误。
  5. 无效参数传递:getAll函数不需要接收favorite参数,当前调用getAll(favorite)属于无效传参。

解决方案

1. 修正Favorite组件的状态更新逻辑

function Favorite() {
  const [favorite, setFavorite] = useState([]);
  const [movies, setMovies] = useState([]);
  const [isLoading, setIsLoading] = useState(true); // 添加加载状态

  async function getAll() {
    try {
      const { data } = await getAllFavorite();
      setFavorite(data);
      const fetchedMovies = [];
      // 遍历收藏的电影标题,批量获取API数据
      for (const title of data) {
        const url = `http://www.omdbapi.com/?s=${encodeURIComponent(title)}&apikey=aea06659`;
        const response = await fetch(url);
        const responseJson = await response.json();
        // 检查是否有搜索结果,避免报错
        if (responseJson.Search && responseJson.Search.length > 0) {
          fetchedMovies.push(responseJson.Search[0]);
        }
      }
      // 一次性更新movies状态
      setMovies(fetchedMovies);
    } catch (error) {
      console.error("获取数据失败:", error);
    } finally {
      setIsLoading(false);
    }
  }

  useEffect(() => {
    getAll(); // 无需传参
  }, []);

  // 渲染时处理加载状态
  if (isLoading) {
    return <div>加载中...</div>;
  }

  return (
    <div className="row">
      {movies.map((movie) => (
        <FavoriteChiled key={movie.imdbID} movie={movie} />
      ))}
    </div>
  );
}

2. 修正子组件的Props接收

function FavoriteChiled(props) {
  // 匹配父组件传递的props名称
  const { movie } = props;
  // 处理海报为空的情况
  const posterUrl = movie.Poster !== "N/A" ? movie.Poster : "默认海报地址";
  
  return (
    <div key={movie.imdbID} className="image-container d-flex justify-content-start m-3">
      <img src={posterUrl} alt={movie.Title} />
    </div>
  );
}

关键优化点

  • 使用临时数组fetchedMovies收集所有API返回的电影数据,一次性调用setMovies更新状态,避免多次更新导致的状态覆盖。
  • 添加encodeURIComponent处理电影标题中的特殊字符,避免API请求失败。
  • 增加加载状态和错误捕获,提升用户体验。
  • 修正子组件的props名称匹配,避免数据未定义。
  • 处理海报为"N/A"的情况,防止图片加载失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 02:40:38