表单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
相关产品推荐
相关产品推荐

