如何使用React Hooks在表单提交时调用API并将结果存入state
错误根因
- 非法Hook调用报错的核心原因是违反了React Hook使用规则:
useEffect只能在函数组件的顶层作用域调用,不能嵌套在submitAction这类事件回调、异步函数内部。 - 原代码还存在逻辑缺失:没有实际发送API请求的步骤,也未定义
response变量,同时按钮标签存在语法错误。
最优解决方案(无需额外useEffect)
表单提交本身就是明确的请求触发时机,不需要额外用布尔变量+useEffect绕一层,直接在提交回调中完成请求发送和state存储即可:
import { useForm } from "react-hook-form"; import { useState } from "react"; function Example() { const { register, handleSubmit } = useForm(); const [storage, setStorage] = useState(null); const submitAction = async (data) => { try { // 拼接请求地址 const url = `你的API基础地址${data.param}`; // 发送API请求,这里用fetch演示,也可以替换为axios等请求库 const response = await fetch(url); const resData = await response.json(); // 直接将结果存入state setStorage(resData); } catch (err) { // 可自行添加错误处理逻辑 console.error('请求失败:', err); } }; return ( <div> <form onSubmit={handleSubmit(submitAction)}> <select {...register('param')}> <option value="something"> something </option> {/* 其余option选项 */} </select> {/* 修复原代码中按钮标签的语法错误 */} <button type="submit">提交</button> </form> </div> ); } export default Example;
如需使用useEffect控制请求的实现方案
如果你需要基于状态驱动请求(比如后续要做参数变更自动重发等需求),可以按以下方式传递参数:
- 新增一个state存储提交的参数,把该参数作为useEffect的依赖项
- 提交时先将参数写入这个state,触发useEffect执行请求
import { useForm } from "react-hook-form"; import { useState, useEffect } from "react"; function Example() { const { register, handleSubmit } = useForm(); const [storage, setStorage] = useState(null); // 新增state存储提交参数 const [submitParam, setSubmitParam] = useState(null); const submitAction = (data) => { // 提交时仅更新参数state,触发useEffect setSubmitParam(data.param); }; // useEffect放在组件顶层,监听submitParam变化 useEffect(() => { // 首次渲染submitParam为null时不发请求 if (submitParam === null) return; const fetchData = async () => { try { const url = `你的API基础地址${submitParam}`; const response = await fetch(url); const resData = await response.json(); setStorage(resData); } catch (err) { console.error('请求失败:', err); } }; fetchData(); }, [submitParam]); // 依赖项为提交的参数,参数变化自动触发请求 return ( <div> <form onSubmit={handleSubmit(submitAction)}> <select {...register('param')}> <option value="something"> something </option> {/* 其余option选项 */} </select> <button type="submit">提交</button> </form> </div> ); } export default Example;
内容的提问来源于stack exchange,提问作者Mistakamikaze
相关产品推荐
相关产品推荐

