我正在尝试设置 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,
},
}
}
非常感谢帮助者!
您需要在
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
如果您使用的是 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>
)
}
就这样,祝您编码愉快!
转到项目的根文件,我猜测是页面文件夹中的 _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>
</>
);
}