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

React中提交表单后无法根据movieName重新请求电影API的问题

问题分析及解决办法

核心问题拆解

你的代码主要存在以下几个导致功能失效或体验不佳的问题:


1. 缺少请求前的loading状态重置

第一次加载时loading初始为true,请求完成后设为false,但后续调用getMovies时没有先将loading重新设为true。这会导致用户提交搜索后,页面没有加载状态反馈,误以为功能未触发。

2. 未处理API请求异常

当前代码没有对fetch请求和JSON解析过程做错误捕获,一旦出现网络问题、API返回异常,会直接抛出错误,导致setMovies和setLoading无法执行,页面状态直接卡住。

3. useEffect依赖数组不完整

getMovies函数依赖movieName,且在useEffect中被调用,但未被加入useEffect的依赖数组。虽然当前场景下movieName变化会触发useEffect,但不符合React最佳实践,容易引发潜在bug,同时会触发ESLint警告。

4. 无结果状态无提示

当搜索关键词没有匹配到电影时,API会返回空的movies数组,页面没有任何提示,用户会误以为功能失效。


修复后的完整代码

import { useEffect, useCallback, useState } from "react";
import Movie from "../components/Movie";

function Home(){
  const [loading, setLoading] = useState(true);
  const [movies, setMovies] = useState([]);
  const [movieSearch, setMovieSearch] = useState('');
  const [movieName, setMovieName] = useState('');

  // 用useCallback包裹,稳定函数引用
  const getMovies = useCallback(async () => {
    setLoading(true); // 请求开始前重置loading状态
    try {
      const response = await fetch(
        `https://yts.mx/api/v2/list_movies.json?minimum_rating=8&page=${Math.round(Math.random()*100)}&query_term=${movieName}&sort_by=year`
      );
      // 检查请求是否成功
      if (!response.ok) {
        throw new Error(`请求失败:${response.status}`);
      }
      const json = await response.json();
      // 用可选链避免json.data不存在时报错
      setMovies(json.data?.movies || []);
    } catch (error) {
      console.error("获取电影数据失败:", error);
      setMovies([]); // 出错时清空电影列表
    } finally {
      setLoading(false); // 无论成功失败都结束加载状态
    }
  }, [movieName]);

  const onChange = (event) =>{
    setMovieSearch(event.target.value)
  }

  const onSubmit = (event)=>{
    event.preventDefault();
    setMovieName(movieSearch)
  }

  useEffect(() => {
    getMovies();
  }, [getMovies]); // 依赖稳定后的getMovies函数

  return (
    <>
      <h4>Search</h4>
      <form onSubmit={onSubmit}>
        <input
          onChange={onChange}
          type="text"
          value={movieSearch}
          placeholder="输入电影名搜索..."
        />
        <button type="submit">搜索</button> {/* 添加提交按钮,交互更直观 */}
      </form>
      {loading ? (
        <h3>Loading</h3>
      ) : (
        <div>
          {movies.length === 0 ? (
            <p>没有找到匹配的电影</p> // 无结果时给出明确提示
          ) : (
            movies.map((item) => (
              <Movie
                key={item.id}
                id={item.id}
                title={item.title}
                year={item.year}
                medium_cover_image={item.medium_cover_image}
                rating={item.rating}
                runtime={item.runtime}
                genres={item.genres}
                summary={item.summary}
              />
            ))
          )}
        </div>
      )}
    </>
  );
}

关键修复说明

  • 重置loading状态:每次调用getMovies时先设置loading=true,确保用户能看到加载反馈。
  • 异常捕获处理:用try/catch包裹请求流程,处理网络错误和API异常,避免页面卡住。
  • useCallback优化:包裹getMovies函数,稳定其引用,同时完善useEffect依赖数组,符合React规范。
  • 无结果提示:当搜索无匹配时显示提示文本,明确告知用户结果状态。
  • 添加提交按钮:原表单仅支持回车提交,添加按钮后交互更友好。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 20:15:46