gpt4 book ai didi

reactjs - Stripe : Could not find Elements context error in nextjs

转载 作者:行者123 更新时间:2023-12-05 04:32:49 41 4
gpt4 key购买 nike

我在 nextjs 12 中使用 stripe following 包

import { loadStripe } from "@stripe/stripe-js";
import { Elements } from "@stripe/react-stripe-js";

它在开发模式下运行良好,但在生产构建时会抛出此错误

Error: Could not find Elements context; You need to wrap the part of your app that calls useStripe() in an <Elements> provider.

我将 Elements 用作父容器,将 Elements 中的 Checkoutform 用作子容器

import React from 'react'
import { useAppContext } from '@/context/AppContext';
import { loadStripe } from "@stripe/stripe-js";
import { Elements } from "@stripe/react-stripe-js";
import Checkoutform from './Checkoutform';
import AppLoader from '@/components/common/Loader';

const Payment = () => {
const { state } = useAppContext();
const { user, planType } = state;
const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_KEY);
const options = {
clientSecret: planType.orderData.client_secret,
appearance: {
theme: 'stripe',
}
};

return (
options.clientSecret && options.clientSecret.length > 0 ? (
<Elements stripe={stripePromise} options={options} >
<Checkoutform userData={user} planType={planType} />
</Elements >
) : (
<AppLoader />
)
)
}


export default Payment

Checkoutform.js

import React, { useEffect, useState } from "react";
import {
PaymentElement,
useStripe,
useElements
} from "@stripe/react-stripe-js";
import AppLoader from "@/components/common/Loader";
import { toast } from "react-toastify";
import { baseURL } from "@/constants/utils/universal";

export default function Checkoutform(props) {
const { userData, planType } = props;
const stripe = useStripe();
const elements = useElements();
const [message, setMessage] = useState(null);
const [isLoading, setIsLoading] = useState(false);
const [isInitialized, setIsInitialized] = useState(true);
const redirectUrl = baseURL + "/pricing/payment/success";


useEffect(() => {
if (typeof window === "undefined" && !stripe) {
return;
}

const clientSecret = new URLSearchParams(window.location.search).get(
"payment_intent_client_secret"
);

if (!clientSecret) {
return;
}
stripe.retrievePaymentIntent(clientSecret).then(({ paymentIntent }) => {
switch (paymentIntent.status) {
case "succeeded":
toast.success("Thankyou!, Payment Successful, please check your email for your receipt");
setMessage("Payment succeeded!");
break;
case "processing":
setMessage("Your payment is processing.");
break;
case "requires_payment_method":
setMessage("Your payment was not successful, please try again.");
break;
default:
setMessage("Something went wrong.");
break;
}
});
}, [stripe]);

useEffect(() => {
setTimeout(() => {
if (typeof window !== "undefined") {
setIsInitialized(false);
}
}, 1000);
}, [])

const handleSubmit = async (e) => {
e.preventDefault();

if (!stripe || !elements) {
return;
}

setIsLoading(true);

const { error } = await stripe.confirmPayment({
elements,
confirmParams: {
return_url: redirectUrl,
},
});

if (error.type === "card_error" || error.type === "validation_error") {
toast.error("Oops! some error occurred, please try again");
setMessage(error.message);
} else {
toast.error("Oops! some error occurred, please try again");
setMessage("An unexpected error occured.");
}

setIsLoading(false);
};

return (
<div className='container my-5 pt-5'>
<div className='row'>
<div className='col-md-6 col-12 mx-auto'>
<div className='card shadow-sm p-5'>
{
!isInitialized ?
<form id="payment-form" onSubmit={handleSubmit}>
<PaymentElement id="payment-element" className="mb-5" />
<div className="mt-3 d-grid">
<button disabled={isLoading || !stripe || !elements} id="submit" className="btn app-cta">
<span id="button-text">
{isLoading ? "processing please wait..." : "Pay now"}
</span>
</button>
</div>
{/* Show any error or success messages */}
{message && <div id="payment-message" className='my-2 small fw-light text-danger'>{message}</div>}
</form>
:
<AppLoader />
}
</div>
</div>
</div>
</div>
);
}

请帮助我我做错了什么或者我必须为生产构建添加什么

最佳答案

Jonathan Steele 是对的,如果您使用 checkoutform.js 作为组件,那么请确保将其保存在 components 文件夹中,该文件夹应该位于 pages 文件夹之外。因为如果它在 pages 文件夹内,那么在构建期间 nextjs 将尝试通过将其视为一个页面来预呈现它,这会给你这个错误

关于reactjs - Stripe : Could not find Elements context error in nextjs,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71586276/

41 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com