ComponentDidMount 被多次调用 [英] ComponentDidMount called multiple times

查看:1222
本文介绍了ComponentDidMount 被多次调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我构建了一个 HOC,用于在我的应用中受保护的路由.它接收应该在路由上呈现的组件,检查用户是否通过身份验证,然后如果通过,则呈现该组件.它可以工作,但会导致组件多次挂载/卸载(与调用 app.js 文件中的渲染函数的次数一样).

I built a HOC to use on protected routes in my app. It takes in the component that should be rendered at the route, checks if the user is authenticated, and then renders that component if they are. It works, but it causes the component to mount/unmount several times (as many times as the render function in my app.js file is called).

来自我的 app.js 的路由

routes from my app.js

<Switch>
    <Route path='/groups/show/:id'
           component={ RequireAuth(Group) } />

    <Route path='/groups/create'
           component={ RequireAuth(CreateGroup) } />

    <Route path='/groups'
           component={ RequireAuth(GroupsMenu) } />

    <Route path='/tutorials/:id' component={ Tutorial } />
    <Route path='/tutorials'     component={ TutorialMenu } />
    <Route path='/ranked'        component={ RankedPlay } />
    <Route path='/casual'        component={ CasualPlay } />
    <Route path='/offline'       component={ OfflinePlay } />
    <Route path='/signup'        component={ Signup } />
    <Route path='/'              component={ Menu } />
</Switch>

require_auth.js

require_auth.js

import React, { Component } from 'react';
import { connect }          from 'react-redux';
import { withRouter }       from 'react-router-dom';
import { store }            from '../../index';
import { AUTH_ERROR }       from '../../actions';
import PropTypes            from 'prop-types';

import Display from './display';

export default function(ComposedComponent) {
    class Authentication extends Component {
        static propTypes = {
            history: PropTypes.object.isRequired
        };

        componentWillMount() {
            const { history } = this.props;
            const error = 'You must be logged in to do this.  Please login';

            if (!this.props.authenticated) {
                store.dispatch({ type: AUTH_ERROR, payload: error });
                history.push('/');
            }
        }

        componentWillUpdate(nextProps) {
            const { history } = this.props;
            const error = 'You must be logged in to do this.  Please login';

            if (!nextProps.authenticated) {
                store.dispatch({ type: AUTH_ERROR, payload: error });
                history.push('/');
            }
        }

        render() {
            return (
                <Display if={ this.props.authenticated } >
                    <ComposedComponent { ...this.props } />
                </Display>
            );
        }
    }

    function mapStateToProps(state) {
        return {
            authenticated: state.auth.authenticated
        };
    }

    return withRouter(connect(mapStateToProps)(Authentication));
}

如果您从任何路由中删除 RequireAuth(),则该组件只会在您点击该路由时安装一次.但是添加它会导致组件在每次 app.js render() 触发时挂载.有没有办法设置这个组件只安装一次?

If you remove RequireAuth() from any of the routes, the component only mounts once when you hit the route. But adding it causes the component to mount every time app.js render() fires. Is there a way I can set this up so the component only mounts once?

推荐答案

通过在渲染中调用 RequireAuth(Component),您在每次渲染中都使用 HOC 装饰 Component调用,使每个渲染返回一个组件.

By calling RequireAuth(Component) in render, you are decorating Component with your HOC in every render call, making that each render returns a new Component each render.

在导出它们之前,您应该使用 RequireAuth 修饰 GroupCreateGroupGroupsMenu.就像使用 react-reduxconnect 一样.

You should decorate Group, CreateGroup and GroupsMenu with RequireAuth, before exporting them. Just as you would with react-redux's connect.

这篇关于ComponentDidMount 被多次调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆