iyzipay支付JS代码在控制台正常,在React应用中不生效如何解决?
问题原因
1. 执行时机不匹配
你在React组件内直接执行初始化代码时,此时组件还未完成挂载,<div id="iyzipay-checkout-form"></div>容器尚未插入到真实DOM中,第三方脚本加载完成后找不到对应容器,自然无法渲染支付表单。你在控制台手动执行代码时,页面已经完成渲染,容器真实存在,因此可以正常生成表单。
2. 变量作用域隔离
React组件内部的作用域和全局window作用域是隔离的,你在组件内声明的var iyziInit是组件局部变量,不会挂载到全局window上。第三方支付脚本加载完成后,默认会从全局window对象读取iyziInit配置,找不到配置就不会执行初始化逻辑。
3. 严格模式重复执行干扰(React18+)
React18默认开启的严格模式在开发环境下会触发组件两次挂载、一次卸载的逻辑,可能导致脚本重复加载、配置被意外清除,进一步影响初始化流程。
解决方案
调整初始化逻辑,保证组件挂载完成后再执行脚本加载,同时将配置暴露到全局作用域,增加卸载清理逻辑避免残留:
import { useEffect } from 'react'; const PaymentForm = () => { useEffect(() => { // 避免重复加载脚本 if (document.getElementById('iyzi-checkout-script')) return; // 将配置挂载到全局window,供第三方脚本读取 window.iyziInit = { currency: "TRY", token: "23bfa27a-172a-493d-b42f-8b091589eaa0", price: 2.4, locale: "tr", baseUrl: "https://sandbox-api.iyzipay.com", merchantGatewayBaseUrl: "https://sandbox-merchantgw.iyzipay.com", registerCardEnabled: true, bkmEnabled: true, bankTransferEnabled: false, bankTransferRedirectUrl: "https://localhost:3000/callback", bankTransferCustomUIProps: {}, campaignEnabled: false, creditCardEnabled: true, bankTransferAccounts: [], userCards: [], fundEnabled: true, memberCheckoutOtpData: {}, force3Ds: false, isSandbox: true, storeNewCardEnabled: true, paymentWithNewCardEnabled: true, enabledApmTypes: ["SOFORT", "IDEAL", "QIWI", "GIROPAY"], payWithIyzicoUsed: false, payWithIyzicoEnabled: true, payWithIyzicoCustomUI: {}, buyerName: "John", buyerSurname: "Doe", merchantInfo: "", cancelUrl: "", buyerProtectionEnabled: false, hide3DS: false, gsmNumber: "", email: "email@email.com", checkConsumerDetail: {}, subscriptionPaymentEnabled: false, ucsEnabled: false, fingerprintEnabled: false, payWithIyzicoFirstTab: false, metadata: {} }; // 动态创建script标签 const iyziJSTag = document.createElement("script"); iyziJSTag.src = "https://sandbox-static.iyzipay.com/checkoutform/v2/bundle.js?v=1634688058781"; iyziJSTag.id = "iyzi-checkout-script"; document.head.appendChild(iyziJSTag); // 组件卸载清理逻辑 return () => { delete window.iyziInit; const existedScript = document.getElementById("iyzi-checkout-script"); if (existedScript) document.head.removeChild(existedScript); const formContainer = document.getElementById("iyzipay-checkout-form"); if (formContainer) formContainer.innerHTML = ""; }; }, []); return <div id="iyzipay-checkout-form"></div>; }; export default PaymentForm;
注意事项
- 确保页面中只有一个
id="iyzipay-checkout-form"的容器,避免id冲突导致脚本找不到正确容器 - 如果开发环境下严格模式导致重复执行问题,可以临时关闭严格模式验证功能,上线后严格模式不会影响生产环境运行
内容的提问来源于stack exchange,提问作者Koray Aydemir
相关产品推荐
相关产品推荐

