知道为什么会出现此错误吗? “错误:usePayPalScriptReducer 必须在 PayPalScriptProvider 中使用”

问题描述 投票:0回答:3

我正在尝试设置 PayPal Checkout... 在开发环境中,它可以工作,但是当我尝试将代码部署到 vercel 时,我不断收到此错误:

Error: usePayPalScriptReducer must be used within a PayPalScriptProvider

知道为什么吗? 我使用服务器端属性和服务器端路径,它有某种关联吗?

Vercel 还生成一个日志,指出它可能与 https://nextjs.org/docs/messages/prerender-error

这是我的 PayPal 组件:

import { PayPalScriptProvider, PayPalButtons } from '@paypal/react-paypal-js'
import {
  getAllBootcampsSlugs,
  getBootcampDataBySlug,
} from './../../../src/utils/bootcampsApi'

function Join() {
  function createOrder(data, actions) {
    return actions.order
      .create({
        purchase_units: [
          {
            amount: {
              value: 5,
            },
          },
        ],
        application_context: {
          shipping_preference: 'NO_SHIPPING',
        },
      })
      .then((orderID) => {
        return orderID
      })
  }

  // handles when a payment is confirmed for paypal
  async function onApprove(data, actions) {
  // Code
  }

  // handles payment errors
  function onError(data, actions) {
  // Code
  }

  return (
<div className="min-h-screen flex flex-col justify-center items-center">
  <PayPalScriptProvider
    options={{
      'client-id': process.env.NEXT_PUBLIC_PAYPAL_CLIENT_ID,
    }}>
    <PayPalButtons
      style={{
        color: 'black',
        label: 'pay',
        tagline: false,
        // layout: 'horizontal',
      }}
      createOrder={createOrder}
      onApprove={onApprove}
      onError={onError}
    />
  </PayPalScriptProvider>
</div>
  )
}

export default Join

// Return the page without additional layout.
Join.getLayout = (page) => page

export async function getStaticPaths() {
  const paths = getAllBootcampsSlugs().map((bootcamp) => ({
    params: {
      bootcamp,
    },
  }))
  return {
    paths,
    fallback: false,
  }
}

export async function getStaticProps(context) {
  // Fetch Data
  const { params } = context
  const data = getBootcampDataBySlug(params.bootcamp)
  return {
    props: {
      data: data,
    },
  }
}

非常感谢帮助者!

next.js paypal
3个回答
1
投票

您需要在

usePayPalScriptReducer
组件中使用
PayPalScriptProvider
,如下所示:

import {
    PayPalScriptProvider,
    PayPalButtons,
    usePayPalScriptReducer
} from "@paypal/react-paypal-js";

const ButtonWrapper = () => {
    // usePayPalScriptReducer can be use only inside children of PayPalScriptProviders
    // This is the main reason to wrap the PayPalButtons in a new component
    const [{ options, isPending }, dispatch] = usePayPalScriptReducer();

    return (
        <PayPalButtons ... />
    )
}

const ProviderWrapper = () => {
    return (
        <PayPalScriptProvider ...>
            <ButtonWrapper />
        </PayPalScriptProvider>
    )
}

export default ProviderWrapper;

有关更多信息,请查看文档:https://paypal.github.io/react-paypal-js/?path=/docs/example-paypalbuttons--default


0
投票

如果您使用的是 nextJs 13,您要做的就是使用客户端指令中的 PayPalScript Provider 包装整个 layout.js

在应用程序目录中,使用以下代码片段创建一个名为“PaypalProvider.js”的文件 ----------------->

'use client'

import { PayPalScriptProvider } from "@paypal/react-paypal-js";


export const PayPalProvider = ({children}) => {
    return <PayPalScriptProvider>{children}</PayPalScriptProvider>
}

然后在你的layout.js中将paypal提供商与其他提供商(如果有的话)包装在一起,就像这样-------------->

import { StoreProvider } from '../store/provider';
import '../styles/globals.scss';
import { Inter } from 'next/font/google';
import { NextAuthProvider } from './Providers';
import { PayPalProvider } from './PayPalProvider';

const inter = Inter({ subsets: ['latin'] })

export const metadata = {
  title: '',
  description: '',
}

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body className={inter.className}>
        <PayPalProvider>
        <NextAuthProvider>
        <StoreProvider>
        {children}
        </StoreProvider>
        </NextAuthProvider>
        </PayPalProvider>
        </body>
    </html>
  )
}

就这样,祝您编码愉快!


0
投票

转到项目的根文件,我猜测是页面文件夹中的 _app.js ,并使用 PayPalScriptProvider 包装整个组件,如下所示:

import { PayPalScriptProvider } from "@paypal/react-paypal-js";
import "@/styles/globals.scss";

export default function App({
  Component,
  pageProps: { session, ...pageProps },
}) {
  return (
    <>
       <PayPalScriptProvider deferLoading={true}>
         <Component {...pageProps} />
       </PayPalScriptProvider>
    </>
  );
}
© www.soinside.com 2019 - 2024. All rights reserved.