React Native中Formik表单提交调用usePostRequest触发Hook规则错误
解决Formik提交时调用自定义Hook的错误问题
错误原因
你触发的错误完全符合Hook规则的第二条:React Hooks只能在函数组件的顶层作用域调用,不能放在事件处理函数(比如handleSubmit这种表单提交回调)、循环、条件判断里。你原来的写法把usePostRequest放在handleSubmit内部,违反了这条规则,所以报错。
正确实现方式
核心思路是:把自定义Hook移到组件顶层调用,让Hook返回一个可以触发请求的函数,然后在handleSubmit里调用这个函数并传入表单值。
1. 改造自定义Hook usePostRequest
让Hook返回一个用于发起请求的方法,而不是直接在Hook内部发起请求:
import { useState } from 'react'; const usePostRequest = (url) => { const [status, setStatus] = useState('idle'); const [data, setData] = useState(null); const [error, setError] = useState(null); // 定义发起请求的函数 const sendRequest = async (payload) => { setStatus('loading'); try { const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', // 可添加token等请求头 }, body: JSON.stringify(payload), }); if (!response.ok) throw new Error('请求失败'); const result = await response.json(); setData(result); setStatus('success'); } catch (err) { setError(err.message); setStatus('error'); } }; return { status, data, error, sendRequest }; };
2. 在组件中正确使用
在组件顶层调用Hook,拿到sendRequest方法后,在handleSubmit里传入表单值触发请求:
import { Formik } from 'formik'; import usePostRequest from './path/to/usePostRequest'; const HolidayRequestForm = () => { // 组件顶层调用Hook,符合规则 const { status, data, error, sendRequest } = usePostRequest("/api/holidays-request"); // 表单提交回调 const handleSubmit = async (values) => { // 用表单的values替换硬编码数据 await sendRequest({ dateFrom: values.dateFrom, dateTo: values.dateTo, fromHalf: values.fromHalf, toHalf: values.toHalf, }); // 根据请求状态做后续处理 if (status === 'success') { alert('申请提交成功'); } else if (status === 'error') { alert(`提交失败:${error}`); } }; return ( <Formik initialValues={{ dateFrom: '', dateTo: '', fromHalf: 0, toHalf: 0, }} onSubmit={handleSubmit} // 直接传入handleSubmit > {/* 你的表单输入组件 */} </Formik> ); }; export default HolidayRequestForm;
额外说明
如果你的usePostRequest原本有自动发起请求的逻辑,记得移除这部分,只保留请求方法和状态管理,这样才能在表单提交时手动触发请求。
内容的提问来源于stack exchange,提问作者WhiteFeather
相关产品推荐
相关产品推荐

