React表单API请求输入不更新,按钮点击页面刷新无数据加载
问题分析与修复方案
核心问题拆解
表单默认提交导致页面刷新
按钮嵌套在<form>标签内,点击时会触发浏览器默认的表单提交行为,直接刷新页面,导致API请求还没完成就被中断。Hook使用违规
useEffect被放在了普通函数ShowPosts内部,违反了React Hook的使用规则——Hook只能在组件顶层或自定义Hook中调用,这会导致逻辑执行异常。事件处理逻辑混淆
提交按钮绑定了处理输入框变化的handleChange函数,完全不符合业务逻辑,点击按钮时根本没有触发API请求的逻辑。依赖项缺失
即使useEffect能正常运行,它的依赖数组为空,只会在组件首次渲染时执行一次,无法响应searchInput的变化。
修正后的完整代码
import React, { useState } from "react" import "../../styles/components.css" import './Recipes.css' const key = 'API_KEY'; export default function Recipes() { const [posts, setPosts] = useState([]); const [searchInput, setSearchInput] = useState(""); const recipesDisplay = posts?.map((response) => ( <div key={response.id} className="list-group-item"> <img src={response.image_url} alt={response.title} /> <h3>{response.title}</h3> <p>By: {response.publisher}</p> </div> )); // 处理输入框内容变化 const handleChange = (e) => { setSearchInput(e.target.value); }; // 封装API请求逻辑 const fetchRecipes = async () => { try { const response = await fetch(`https://forkify-api.herokuapp.com/api/v2/recipes?search=${searchInput}&key=${key}`); if (response.ok) { const jsonResponse = await response.json(); setPosts(jsonResponse.data.recipes); } } catch (err) { console.log(err); } }; // 处理表单提交 const handleSubmit = (e) => { e.preventDefault(); // 阻止表单默认提交行为 if (searchInput.trim()) { // 空输入不发起请求 fetchRecipes(); } }; return ( <div className="main"> <h1>Recipes</h1> <form onSubmit={handleSubmit}> {/* 绑定表单提交事件 */} <input type="search" placeholder="Search here" onChange={handleChange} value={searchInput} /> <button type="submit">Submit</button> {/* 按钮类型设为submit */} </form> {recipesDisplay} </div> ) }
关键修改说明
- 移除了违规的
ShowPosts函数,将API请求逻辑封装为独立的fetchRecipes函数 - 给
<form>添加onSubmit事件处理函数handleSubmit,在其中阻止默认提交行为并发起API请求 - 提交按钮改为
type="submit",绑定正确的提交逻辑 - 移除了
handleChange中无效的e.preventDefault()(输入框的onChange事件不需要阻止默认) - 若需要输入框内容变化时自动请求,可添加如下
useEffect到组件顶层:useEffect(() => { if (searchInput.trim()) { fetchRecipes(); } }, [searchInput]);
内容的提问来源于stack exchange,提问作者Rekcut23
相关产品推荐
相关产品推荐

