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

React表单API请求输入不更新,按钮点击页面刷新无数据加载

问题分析与修复方案

核心问题拆解

  1. 表单默认提交导致页面刷新
    按钮嵌套在<form>标签内,点击时会触发浏览器默认的表单提交行为,直接刷新页面,导致API请求还没完成就被中断。

  2. Hook使用违规
    useEffect被放在了普通函数ShowPosts内部,违反了React Hook的使用规则——Hook只能在组件顶层或自定义Hook中调用,这会导致逻辑执行异常。

  3. 事件处理逻辑混淆
    提交按钮绑定了处理输入框变化的handleChange函数,完全不符合业务逻辑,点击按钮时根本没有触发API请求的逻辑。

  4. 依赖项缺失
    即使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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 23:35:21