JS 代码在我将其粘贴到控制台时有效,但在我的 React App 中不起作用

JS code works when i paste it on console, but does not work inside my React App

好的,有代码:

var 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: {},
  createTag: function() {
    var iyziJSTag = document.createElement("script");
    iyziJSTag.setAttribute(
      "src",
      "https://sandbox-static.iyzipay.com/checkoutform/v2/bundle.js?v=1634688058781"
    );
    document.head.appendChild(iyziJSTag);
  },
};
iyziInit.createTag();

此代码在 <div id="iyzipay-checkout-form"></div>.

中创建了一个完整的付款表单

我不能把它当作普通的 React 代码,因为它来自 api 支付网关提供商。此脚本需要 运行 并将这些元素直接添加到 dom.

问题是:

如果我将此代码粘贴到浏览器的控制台,它 运行s 将脚本标记添加到文档的头部,然后在 div 中创建我的表单。我可以看到表格。

但是,如果我将此代码放入我的 React 应用程序中,它 运行s 将脚本标签添加到文档的头部,然后什么也不会发生。表单未创建,我的 div id 为“iyzipay-checkout-form”是空的。

为什么?我快疯了,两天都想不通。

也应该提到这一点:如果我创建一个独立的 index.html,请将此代码放在文档头部的脚本标记中,然后只需添加一个 ID 为“iyzipay-checkout”的 div -form”,这确实会在该 html 页面上创建表单。因此该代码仅在 react 中不起作用。

您可以在 React Playground 上进行测试:https://codesandbox.io/s/react-playground-forked-4ht85

在您看到的页面上,即使有创建它的代码,您也看不到该表单,但是如果您打开 playground 的控制台,并粘贴我在这个问题的顶部,表格将出现。您也可以右键检查,查看 head 标签和其中创建的内容。

所以问题是 iyziInit.createTag(); 注入的脚本期望 iyziInit 变量在全局范围内定义(附加到 window)。

下面是一个可以正常工作并显示表单的示例。

import logo from "./logo.svg";
import "./App.css";

import { useEffect, useState } from "react";

function MyComp() {
  const [, setCalled] = useState(false);

  useEffect(() => {
    setCalled(called => {
      if (!called) {
        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: {},
          createTag: function() {
            var iyziJSTag = document.createElement("script");
            iyziJSTag.setAttribute(
              "src",
              "https://sandbox-static.iyzipay.com/checkoutform/v2/bundle.js?v=1634688058781"
            );
            document.head.appendChild(iyziJSTag);
          }
        };
        window.iyziInit.createTag();
        return true;
      }
    });

    return () => delete window.iyziInit;
  }, []);

  return <></>;
}

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
      <MyComp />
    </div>
  );
}

export default App;