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

ReactJS项目中表单提交按钮需点击两次才生效的问题该如何修复?

React表单提交重复点击才跳转问题修复方案

问题原因

React的setSubmitted是异步更新函数,状态更新后要等到下一次组件渲染才会生效。同时handleSubmit函数内部的submitted变量被当前渲染周期的闭包捕获,值是固定的:

  • 第一次点击提交时,闭包内的submitted是初始值false,调用setSubmitted(true)后状态没有立即更新,后续判断if (submitted)拿到的还是旧值,跳转逻辑不触发
  • 第二次点击提交时,上一次更新的submitted: true已经在新的渲染周期生效,闭包内的submitted值为true,判断成立所以可以跳转

修复方案

方案1:直接在请求成功后执行跳转(最推荐)

你的需求本身就是提交成功后直接跳转,不需要额外依赖submitted状态做判断,直接简化代码即可:

import { useHistory } from 'react-router-dom';
import { useState } from 'react';

function OrderForm() {
  const history = useHistory();

  const handleSubmit = (e) => {
    e.preventDefault();

    fetch('http://localhost:8000/orders', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ cart: 1 }), // 替换为实际表单数据
    })
    .then((response) => {
      if (!response.ok) throw new Error('提交请求失败');
      return response.json();
    })
    .then(() => {
      // 提交成功直接跳转,不需要判断状态
      history.push('/thank-you-page');
    })
    .catch((err) => {
      // 增加错误处理,给用户失败提示
      console.error('提交出错:', err);
      alert('订单提交失败,请稍后重试');
    });
  };

  return (
    <form onSubmit={handleSubmit}>
      {/* 表单内容 */}
      <button type="submit">提交订单</button>
    </form>
  );
}

方案2:保留submitted状态的修复方式

如果你的业务逻辑中确实需要submitted状态(比如控制提交按钮禁用、加载动画展示等),可以通过useEffect监听submitted的变化触发跳转:

import { useHistory } from 'react-router-dom';
import { useState, useEffect } from 'react';

function OrderForm() {
  const history = useHistory();
  const [submitted, setSubmitted] = useState(false);
  const [loading, setLoading] = useState(false);

  // 监听submitted状态变化,为true时执行跳转
  useEffect(() => {
    if (submitted) {
      history.push('/thank-you-page');
    }
  }, [submitted, history]);

  const handleSubmit = (e) => {
    e.preventDefault();
    setLoading(true);

    fetch('http://localhost:8000/orders', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ cart: 1 }), // 替换为实际表单数据
    })
    .then((response) => {
      if (!response.ok) throw new Error('提交请求失败');
      return response.json();
    })
    .then(() => {
      setSubmitted(true);
    })
    .catch((err) => {
      console.error('提交出错:', err);
      alert('订单提交失败,请稍后重试');
      setLoading(false);
    });
  };

  return (
    <form onSubmit={handleSubmit}>
      {/* 表单内容 */}
      <button type="submit" disabled={loading}>
        {loading ? '提交中...' : '提交订单'}
      </button>
    </form>
  );
}

内容的提问来源于stack exchange,提问作者Olsza100

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 21:48:02