警告:只能更新已安装或安装的组件

时间:2017-11-17 21:22:23

标签: javascript reactjs

这是完整的错误:

index.js:2177 Warning: Can only update a mounted or mounting component. This usually means you called setState, replaceState, or forceUpdate on an unmounted component. This is a no-op.

这是什么意思?我在做什么就是产生错误?

这是我的登录页面:

/* global gapi */

class SignIn extends React.Component{

    constructor(props){
        super(props);
        this.state = {
            redirect: false

        }
        this.onSignIn = this.onSignIn.bind(this)
        this.updateRedirect = this.updateRedirect.bind(this)
        // this.test = this.test.bind(this)
    }

     componentWillMount() {
        console.log('componentWillMount ran')
        gapi.load('auth2', () => {
            gapi.auth2.init({
                client_id: '817677528939-dss5sreclldv1inb26tb3tueac98d24r'
            }).then((auth2) => {
                console.log( "signed in: " + auth2.isSignedIn.get())
                this.setState({
                    redirect: auth2.isSignedIn.get()
                })
            })
        })
    }

    updateRedirect() {
        this.setState({
            redirect: true
        })
    }

    componentDidMount() {
        gapi.signin2.render('my-signin2', {
            'scope': 'profile email',
            'width': 300,
            'height': 50,
            'longtitle': true,
            'theme': 'dark',
            'onsuccess': this.onSignIn,
        });
    }


    onSignIn(googleUser) {
        console.log('this ran')
        var profile = googleUser.getBasicProfile();
        console.log('ID: ' + profile.getId()); // Do not send to your backend! Use an ID token instead.
        console.log('Name: ' + profile.getName());
        console.log('Image URL: ' + profile.getImageUrl());
        console.log('Email: ' + profile.getEmail()); // This is null if the 'email' scope is not present.
        this.updateRedirect()
    }

    render() {
        return (
            this.state.redirect ?
            <Redirect to='/options' />
            :
            <div>
                <AppBar title="Pliny" showMenuIconButton={false} zDepth={2} />
                <div id="my-signin2"></div>
            </div>
        )
    }    
}

export default SignIn

由于某些原因,当页面加载时,它会在重新路由之前加载<div id="my-signin2"></div>一秒钟。因此,用户在屏幕上看到登录页面闪烁,然后路由到正确的页面。

有没有办法让它在页面加载之前重新路由?

理想情况下,我想查看用户是否已登录,如果是,请立即将他转到特定页面。如果用户登录,则向其显示登录页面(<div>

2 个答案:

答案 0 :(得分:1)

在将gapi.load方法移动到更高的组件之前,您将始终看到该闪存。它调用的函数是一个promise,这意味着您的组件将在请求该函数时继续呈现。我会将该部分移动到更高级别的部件中,并使您的登录页面成为该部件的子级。

编辑:

以下是一个例子:

class AuthUser extends React.Component {
    constructor(props){
        super(props);
        this.state = {
            redirect: false
            loaded: false
        }
        this.onSignIn = this.onSignIn.bind(this)
        this.updateRedirect = this.updateRedirect.bind(this)
        // this.test = this.test.bind(this)
    }

    onSignIn(googleUser) {
        console.log('this ran')
        var profile = googleUser.getBasicProfile();
        console.log('ID: ' + profile.getId()); // Do not send to your backend! Use an ID token instead.
        console.log('Name: ' + profile.getName());
        console.log('Image URL: ' + profile.getImageUrl());
        console.log('Email: ' + profile.getEmail()); // This is null if the 'email' scope is not present.
        this.updateRedirect()
    }
    componentWillMount() {
        console.log('componentWillMount ran')
        gapi.load('auth2', () => {
            gapi.auth2.init({
                client_id: '817677528939-dss5sreclldv1inb26tb3tueac98d24r'
            }).then((auth2) => {
                console.log( "signed in: " + auth2.isSignedIn.get())
                this.setState({
                    redirect: auth2.isSignedIn.get(),
                    loaded: true
                })
            })
        })
    }
    componentDidMount() {
        gapi.signin2.render('my-signin2', {
            'scope': 'profile email',
            'width': 300,
            'height': 50,
            'longtitle': true,
            'theme': 'dark',
            'onsuccess': this.onSignIn,
        });
    }
    updateRedirect() {
        this.setState({
            redirect: true
        });
    }
    render() {
        if(!this.state.loaded) {
            return null
        }
        return this.state.redirect ? <Redirect to='/options' /> : <SignIn />;
    }
}

class SignIn extends React.Component{
    render() {
        return (
            <div>
                <AppBar title="Pliny" showMenuIconButton={false} zDepth={2} />
                <div id="my-signin2"></div>
            </div>
        )
    }
}

现在,直到auth请求完成后才会呈现<SignIn />组件并且用户没有被重定向。

答案 1 :(得分:0)

您似乎在this.setState中呼叫componentWillMount。顾名思义,该组件当时尚未安装 - 因此您的错误。

相关问题