遇到Stripe问题的我的电子商务网站应用程序
P粉593649715
P粉593649715 2023-09-05 09:15:39
[React讨论组]

我需要创建一个自定义组件,只是为了获取卡片信息并将其存储在Stripe上,以便以后可以对其进行收费。

v3:1 Uncaught (in promise) IntegrationError: 我们无法从指定的元素中检索数据。
请确保您要使用的元素仍然已挂载。
    at ni (v3:1:319630)
    at e._handleMessage (v3:1:324970)
    at e._handleMessage (v3:1:146061)
    at v3:1:322539

出现了这个错误,我已经检查了组件是否已挂载,但是一直以来都是挂载的,因为这是Stripe的工作方式,所有的Stripe组件都在不同的,为我们的应用程序带来了额外的负载,但这是另一个话题。

我需要摆脱这个错误。

我有一个使用stripe.checkout.sessions.create的路由,但它会将用户重定向到另一个标签页,这不是我想要的行为,我更喜欢在同一个应用程序中弹出窗口并在那里获取卡片数据并存储。

在index中传递stripe引用(用于全局访问)

import {Elements} from "@stripe/react-stripe-js";
import {loadStripe} from "@stripe/stripe-js";
const stripePromise = loadStripe(process.env.REACT_APP_STRIPE_PUBLISHABLE_KEY);

...others

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <React.StrictMode>
        <BrowserRouter>
            <Provider store={store}>
                <Elements stripe={stripePromise}>
                    <ThemeProvider>
                        <App/>
                    </ThemeProvider>
                </Elements>
            </Provider>
        </BrowserRouter>
    </React.StrictMode>
);

Stripe CardInput Wrapper(就像文档中的一样) 注意:我在嵌套组件之前在一个空项目中尝试了这段代码,可以完美运行。

import React, {useState} from 'react';
import {CardElement} from '@stripe/react-stripe-js';
import {styled} from "@mui/material/styles";
import {Box, Stack, Typography} from "@mui/material";
import EzLoadingBtn from "../../ezComponents/EzLoadingBtn/EzLoadingBtn";

const CARD_ELEMENT_OPTIONS = {
    style: {
        base: {
            'color': '#32325d',
            'fontFamily': '"Helvetica Neue", Helvetica, sans-serif',
            'fontSmoothing': 'antialiased',
            'fontSize': '16px',
            '::placeholder': {
                color: '#aab7c4',
            },
        },
        invalid: {
            color: '#fa755a',
            iconColor: '#fa755a',
        },
    },
};

const RootStyle = styled(Stack)(({theme}) => ({
    width: '400px',
    padding: '50px 30px 30px 30px'
}))

export default function CardInput({onSubmit}) {
    const [loading, setLoading] = useState(false);
    return (
        <RootStyle>
            <Box component='form' onSubmit={onSubmit}>
                <Stack flexDirection='row' justifyContent='space-between' sx={{marginBottom: '25px'}}>
                    <Typography variant='span'>Card</Typography>
                </Stack>
                <CardElement options={CARD_ELEMENT_OPTIONS}/>
                <EzLoadingBtn
                    sx={{marginTop: '25px'}}
                    color="inherit"
                    size='large'
                    type='submit'
                    variant='outlined'
                    loading={loading}
                >
                    Save Card
                </EzLoadingBtn>
            </Box>
        </RootStyle>
    );
}

P粉593649715
P粉593649715

全部回复(1)
P粉738346380

DONE - 问题是,我曾经认为“包装”整个应用程序

<Elements stripe={stripePromise}>
   <ThemeProvider>
      <App/>
   </ThemeProvider>
</Elements>

足够了,但事实并非如此。 关键是不必将整个应用程序都包装在Elements中,只需将要使用某些stripe组件(CardElement、PaymentElement等)的子组件包装起来即可。

/*父组件*/
<Elements stripe={stripePromise} options={options}>
    <CardInput/>
</Elements>

/*子组件*/
export default function CardInput() {
    return (
        <div>
            <PaymentElement/>
        </div>
    );
}

这样你就准备好了。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号