繁体   English   中英

如何解决 Stripe 元素的反应导致 memory 重定向泄漏

[英]How to solve Stripe elements for react causing memory leak on redirect

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

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

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 中做的最后一件事,当它意味着重定向时。

与 Formik 类似的情况,您会收到此警告:

警告:无法对未安装的组件执行 React state 更新。 这是一个空操作,但它表明您的应用程序中存在 memory 泄漏。 要修复,请取消 useEffect 清理中的所有订阅和异步任务 function。

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

callSomeSaveAction(...)
.then(...)
.catch(...)
.finally(() => setSubmitting(false));

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

发生这种情况是因为重定向卸载了 formik 组件,但无论如何都会调用 setSubmitting。

希望你能用这样的东西解决你的问题。 因为我知道组件将由于重定向而被卸载,所以我在重定向时不需要setSubmitting(false) ,但我仍然需要它以防发生错误:

callSomeSaveAction(...)
.then(...)
.catch(() => {
    ...
    setSubmitting(false);
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM