如何使用react-query提交表单?解决钩子调用无效错误
解决React Query表单提交调用Mutation的Hook错误问题
你遇到的错误:
Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
核心原因是在事件处理函数内部调用了自定义Hook,违反了React的Hook规则——Hook必须在函数组件的顶层作用域调用,不能嵌套在循环、条件判断或事件处理函数中。
修正步骤
1. 调整自定义Hook结构
将请求参数从Hook的入参改为mutationFn的入参,让Hook返回用于触发请求的mutate函数:
const useCreateSupplier = () => { return useMutation({ mutationFn: (createSupplierCommand: CreateSupplierCommand) => axiosClient .post("/supplier", { createSupplierCommand }) .then((res: AxiosResponse) => res.data), onSuccess: async () => { await queryClient.invalidateQueries({ queryKey: [queries.get_suppliers], }); }, }); };
2. 重构表单组件
在组件顶层调用Hook获取mutate函数,同时用useState管理表单输入值,最后在提交事件中触发请求:
import { useState } from 'react'; const CreateSupplierForm = () => { // 在组件顶层调用Hook,获取触发请求的函数 const { mutate: createSupplier } = useCreateSupplier(); // 用state绑定表单输入值 const [name, setName] = useState(''); const [website, setWebsite] = useState(''); const handleSubmit = (event: React.FormEvent) => { event.preventDefault(); // 调用mutate函数,传入表单收集的参数 createSupplier({ name, website }); // 可选:提交后清空表单 setName(''); setWebsite(''); }; return ( <> <form className="row mt-3 mb-4" onSubmit={handleSubmit}> <div className="col-auto"> <input type="text" className="form-control" placeholder="name" value={name} onChange={(e) => setName(e.target.value)} /> </div> <div className="col-auto"> <input type="text" className="form-control" placeholder="website" value={website} onChange={(e) => setWebsite(e.target.value)} /> </div> <div className="col-auto d-flex align-items-center"> <button type="submit" className="btn btn-sm btn-primary"> Add </button> </div> </form> </> ); };
关键说明
- 遵守Hook规则:
useCreateSupplier现在在组件顶层执行,完全符合React对Hook调用位置的要求。 - 表单数据管理:通过
useState绑定输入框,确保能获取用户实际输入的内容,替代原代码中的硬编码值。 - 触发请求的正确方式:在提交事件中调用从Hook获取的
mutate函数,传入请求参数,既不会触发Hook错误,也能正确执行创建供应商的请求。
内容的提问来源于stack exchange,提问作者Muflix
相关产品推荐
相关产品推荐

