React表单提交报错:useState在非组件/自定义Hook函数中调用如何解决?
问题解决方法
错误原因
- Hook调用违规:
useState被写在了handleFormSubmit普通回调函数里,违反了React Hook必须在组件顶层或自定义Hook中调用的规则。 - 函数组件误用类组件语法:代码里用了
this.state.value和this.handleChange,但这是类组件的写法,函数组件需用useState管理状态。 - 表单提交逻辑错误:
onSubmit的回调参数是事件对象,不是直接的表单值,需正确获取输入内容。
修改后的代码(尽量保留原HTML结构)
import React, { useState } from 'react'; const FooterOne = ({ footerLight }) => { // 将response状态移到组件顶层,符合Hook规则 const [response, setResponse] = useState(""); // 用useState管理输入框的email值 const [email, setEmail] = useState(""); const handleFormSubmit = async (e) => { // 阻止表单默认提交行为 e.preventDefault(); const body = { email, }; try { const result = await fetch( `https://.....lambda-url.us-east-1.on.aws/`, { method: "POST", body: JSON.stringify(body), // 新增Content-Type头,确保后端能解析JSON headers: { "Content-Type": "application/json" } } ); const resText = await result.text(); setResponse(resText); // 提交后清空输入框 setEmail(""); } catch (error) { console.error("提交失败:", error); setResponse("提交失败,请稍后重试"); } }; return ( <> <form className='newsletter-form position-relative d-block d-lg-flex d-md-flex' onSubmit={handleFormSubmit} > <input type='email' // 改为email类型更符合语义,其余HTML属性完全保留 className='input-newsletter form-control me-2' placeholder='Enter your email' name='email' required='' autoComplete='off' value={email} onChange={(e) => setEmail(e.target.value)} // 替换原类组件的handleChange写法 /> <input type='submit' value='Subscribe' data-wait='Please wait...' className='btn btn-primary mt-3 mt-lg-0 mt-md-0' /> {/* 可选:添加提交结果提示 */} {response && <p className="mt-2">{response}</p>} </form> </> ); }; export default FooterOne;
关键改动说明
- 把
response的useState移到组件顶层,修复Hook调用违规问题。 - 新增
email状态绑定输入框,仅修改value和onChange属性,原HTML结构基本未动。 - 修正
handleFormSubmit的参数为事件对象,添加e.preventDefault()阻止页面跳转。 - 给POST请求补充
Content-Type头,避免后端无法解析JSON数据。
内容的提问来源于stack exchange,提问作者Peter Penzov
相关产品推荐
相关产品推荐

