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

React页面渲染两个PayPal无代码按钮失败问题求助

React 中渲染多个 PayPal 托管按钮的解决方案

核心问题排查

你遇到的问题主要来自三个关键错误:

  1. 容器元素缺失:你的PayPalButton组件只返回了#paypal-container容器,没有包含第二个按钮需要的#paypal-container1,导致第二个按钮没有渲染目标
  2. 托管按钮ID重复:两个按钮使用了同一个hostedButtonId,这会导致渲染相同的按钮或覆盖
  3. SDK重复加载风险:拆分组件时多次加载PayPal SDK会引发冲突

方案1:单个组件渲染两个按钮

直接修改PayPalButton组件,补充容器并修正按钮ID:

const PayPalButton = () => {
  useEffect(() => {
    // 避免重复加载SDK
    let script = document.querySelector('script[src^="https://www.paypal.com/sdk/js"]');
    const needLoadScript = !script;

    if (needLoadScript) {
      script = document.createElement("script");
      script.src = "https://www.paypal.com/sdk/js?client-id=YOUR_ACTUAL_CLIENT_ID&components=hosted-buttons&enable-funding=venmo&currency=USD";
      script.async = true;
      document.body.appendChild(script);
    }

    // 渲染按钮的统一逻辑
    const renderButtons = () => {
      // 49美元按钮:替换为对应托管按钮ID
      window.paypal.HostedButtons({
        hostedButtonId: "HOSTED_BUTTON_ID_FOR_49USD",
      }).render("#paypal-container-49");

      // 1000美元按钮:替换为对应托管按钮ID
      window.paypal.HostedButtons({
        hostedButtonId: "HOSTED_BUTTON_ID_FOR_1000USD",
      }).render("#paypal-container-1000");
    };

    // 根据SDK加载状态执行渲染
    if (needLoadScript) {
      script.onload = renderButtons;
    } else {
      renderButtons();
    }

    // 清理逻辑:仅移除当前组件创建的脚本
    return () => {
      if (needLoadScript && script) {
        document.body.removeChild(script);
      }
    };
  }, []);

  // 返回两个按钮的容器元素
  return (
    <div className="paypal-button-group">
      <div id="paypal-container-49" className="paypal-buttons"></div>
      <div id="paypal-container-1000" className="paypal-buttons"></div>
    </div>
  );
}

方案2:拆分独立组件(避免耦合)

如果想拆分两个按钮为独立组件,需要确保SDK只加载一次,可通过自定义Hook实现:

1. 创建全局SDK加载Hook

import { useState, useEffect } from 'react';

const usePayPalSDK = () => {
  const [isSDKLoaded, setIsSDKLoaded] = useState(false);

  useEffect(() => {
    // 检查是否已加载SDK
    const existingScript = document.querySelector('script[src^="https://www.paypal.com/sdk/js"]');
    if (existingScript) {
      setIsSDKLoaded(true);
      return;
    }

    // 加载SDK
    const script = document.createElement("script");
    script.src = "https://www.paypal.com/sdk/js?client-id=YOUR_ACTUAL_CLIENT_ID&components=hosted-buttons&enable-funding=venmo&currency=USD";
    script.async = true;
    script.onload = () => setIsSDKLoaded(true);
    document.body.appendChild(script);

    return () => {
      document.body.removeChild(script);
    };
  }, []);

  return isSDKLoaded;
};

2. 创建独立按钮组件

// 49美元按钮组件
const PayPalButton49 = () => {
  const isSDKLoaded = usePayPalSDK();

  useEffect(() => {
    if (isSDKLoaded) {
      window.paypal.HostedButtons({
        hostedButtonId: "HOSTED_BUTTON_ID_FOR_49USD",
      }).render("#paypal-button-49");
    }
  }, [isSDKLoaded]);

  return <div id="paypal-button-49" className="paypal-buttons"></div>;
};

// 1000美元按钮组件
const PayPalButton1000 = () => {
  const isSDKLoaded = usePayPalSDK();

  useEffect(() => {
    if (isSDKLoaded) {
      window.paypal.HostedButtons({
        hostedButtonId: "HOSTED_BUTTON_ID_FOR_1000USD",
      }).render("#paypal-button-1000");
    }
  }, [isSDKLoaded]);

  return <div id="paypal-button-1000" className="paypal-buttons"></div>;
};

3. 在服务页面使用组件

const ServicesPage = () => {
  return (
    <div className="container">
      <Title subTitle='Our Services' title='What We Offer' />
      <Services />
      <PayPalButton49 />
      <PayPalButton1000 />
    </div>
  );
}

关键注意事项

  • 每个托管按钮必须使用唯一的hostedButtonId:在PayPal后台创建两个不同金额的托管按钮,分别获取对应的ID
  • 不要重复加载SDK:多次加载会导致全局变量冲突,引发按钮渲染失败
  • 确保容器ID唯一:每个按钮对应独立的DOM容器,ID不能重复

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 20:50:28