javascript - 如何解决 Stripe 元素 react 导致重定向内存泄漏

标签 javascript reactjs react-hooks stripe-payments

我有一个组件,让我的用户可以选择订阅以从应用程序中删除广告。我完美地集成了 Stripe,直到我来到应用程序的重定向部分。因为如果我的用户有一个事件订阅(我从 firebase db 获得),我不想让人们创建多个订阅,所以我想将我的用户重定向到另一个页面。这导致我在重定向发生后看到有关内存泄漏的警告。在尝试导航回订阅组件后,这种情况不再发生。这是我的组件,其中包含大多数不会导致错误显示的代码。我认为这是 strip 元素,因为如果我删除对该组件的调用,那么一切正常,并且没有内存泄漏。有没有人遇到过这个问题并有解决方法?

我觉得这与我使用 React.useEffect 钩子(Hook)设置显示表单的方式有关。任何帮助都非常感谢!

import React, { Component } from 'react';
import { compose } from 'recompose';
import { Elements } from '@stripe/react-stripe-js';
import { loadStripe } from '@stripe/stripe-js';
import { Redirect } from 'react-router-dom';
import StripeForm from '../components/StripeForm';
import Grid from '@material-ui/core/Grid';


import {
    AuthUserContext,
    withAuthorization,
    withEmailVerification,
} from '../components/Session';
import { withFirebase } from '../components/Firebase';
const stripePromise = loadStripe('stripe-key-here');



const AccountPage = (props) => {
    const show = props.firebase.userData.stripe.subscriptions.subscription.plan.active
    const [showForm, setShowForm] = React.useState(show)

    React.useEffect(() => {
        if (show !== showForm) {
            setShowForm(show);
        }
    }, [show, showForm])

    return (

        <AuthUserContext.Consumer>
            {authUser => {
                return (
                    <>
                        {showForm ? <Redirect to="/thank-you" /> : null}
                        <Grid container spacing={3} style={{ background: '#fff', maxWidth: '94%', margin: '20px auto', borderRadius: 7 }}>
                            <Grid item xs={12} sm={6} style={{ padding: '20px 50px', textAlign: 'justify', }}>
                                <UpgradeMessage />
                            </Grid>
                            <Grid item xs={12} sm={6} style={{ padding: '20px 50px' }}>
                                <div style={{ textAlign: 'justify' }}>
                                    <h3>Purchase a subscription for $9/year!</h3>
                                    <p>Purchasing a subscription will remove the ads from the app and will help us stay up and running!</p>
                                </div>
                                <Elements stripe={stripePromise}>
                                    <div style={{ padding: 15, borderRadius: 10, border: 'solid 4px #fafafa' }}>
                                        <StripeForm setShowForm={setShowForm} firebase={props.firebase} authUser={authUser} />
                                    </div>
                                </Elements>
                            </Grid>
                        </Grid>
                    </>
                )
            }
            }
        </AuthUserContext.Consumer>
    )
};

class LoginManagementBase extends Component {
    constructor(props) {
        super(props);

        this.state = {
            activeSignInMethods: [],
            error: null,
        };
    }

    render() {
        return (
            <div>
                <button onClick={() => this.props.firebase.doSignOut()}>Log out of this app!!!</button>
            </div>
        );
    }
}

const LoginManagement = withFirebase(LoginManagementBase);

const condition = authUser => !!authUser;

export default compose(
    withEmailVerification,
    withAuthorization(condition),
    withFirebase,
)(AccountPage);

最佳答案

您可能需要研究 StripeForm 来解决这个问题。

调用 setShowForm 后 StripeForm 会发生什么?
我假设 setShowForm 之后有一些代码,但使用来自 setShowForm 的重定向被调用: Grid、Elements 和 StripeForm 组件被卸载,它会给你这个警告。

如果这确实是您的问题,setShowForm当它打算重定向时,应该是您在 StripeForm 中做的最后一件事。

A similar case with Formik ,你有这个警告:

Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.



当您提交表单时,您调用一些操作来保存它,一旦完成,Formik 需要知道它已完成 setSubmitting(false); .
事情就是这样:
callSomeSaveAction(...)
.then(...)
.catch(...)
.finally(() => setSubmitting(false));

在您决定在 callSomeSaveAction.then 中使用重定向之前,它工作正常

发生这种情况是因为重定向卸载了 formik 组件,但仍然调用了 setSubmitting。

希望你能用这样的东西解决你的问题。
由于我知道组件将由于重定向而被卸载,所以我不需要 setSubmitting(false)当我重定向时,但我仍然需要它以防发生错误:
callSomeSaveAction(...)
.then(...)
.catch(() => {
    ...
    setSubmitting(false);
});

关于javascript - 如何解决 Stripe 元素 react 导致重定向内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61830574/

相关文章:

reactjs - useEffect hook - 依赖项 - 重新渲染问题

reactjs - 用 react 钩子(Hook)构建的振荡器不会停止

javascript - 为什么 Internet Explorer 会中断弹出窗口中的每个单词?

javascript - 如何在 iframe 中发生点击时触发事件?

reactjs - 如何将公共(public)文件夹添加到react-boilerplate webpack配置中?

reactjs - TS2339 : Property X does not exist on type '{}'

reactjs - 无法在呈现不同组件 (`App` 时更新组件 (`UserTable` )

javascript - 我需要从文本框中动态打印文本。这是从 mysql 加载的。

javascript - 收银机上滑/滑下效果

javascript - React.js 在一定时间后状态发生变化