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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 02:06:27