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
相关产品推荐
相关产品推荐

