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

表单onSubmit回调paymentHandler需点击两次提交按钮才触发的问题咨询

问题分析与解决方案

核心问题1:React状态更新异步导致首次跳转失效

你在paymentHandler里调用await callPaystack()后立刻用paymentResult跳转,但React的setPaymentResult是异步操作——第一次点击时,callPaystack里的状态更新还没完成,paymentResult还是初始的空值/旧值,所以location.href找不到authorization_url,看起来没反应;第二次点击时状态已经更新,所以能正常跳转。

核心问题2:提交按钮未显式指定type="submit"

虽然HTML按钮默认类型是submit,但Styled Components封装的按钮可能丢失默认行为,显式指定type="submit"能确保点击时触发表单的onSubmit回调。


修复后的代码(推荐方案)

const callPaystack = async () => {
  const res = await fetch('https://api.paystack.co/transaction/initialize', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${import.meta.env.VITE_PAYSTACK_SECRET_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      email: buyerEmail, 
      amount: totalPrice * 100,
      channels: ["card", "bank", "qr", "ussd"],
      metadata: {
        "cancel_action": "https://crown-storex.netlify.app",
      }
    }),
  });
  const data = await res.json();
  setPaymentResult(data); // 保留状态用于其他逻辑(如果需要)
  location.href = data.data.authorization_url; // 直接用接口返回的数据跳转,不依赖异步状态
}

const paymentHandler = (e) => {
  e.preventDefault();
  callPaystack();
}

// 表单部分:给按钮显式添加type="submit"
<form onSubmit={paymentHandler}>
  <FormInput
    label="Email"
    name="email"
    type="email"
    value={buyerEmail}
    onChange={(e) => setBuyerData({ ...buyerData, buyerEmail: e.target.value })}
    required
  />
  <Button 
    type="submit" 
    buttonType={buyerEmail ? "inverted" : "disabled"} 
  >Pay Now With Paystack</Button>
</form>

额外提示

  • 别在callPaystack的then里直接console.log(paymentResult),因为状态更新异步,这里打印的还是旧值,要打印就直接用接口返回的data。
  • 确保第一次点击时buyerEmail和totalPrice已经有有效值,避免接口请求失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 20:52:38