这是完整的错误:
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>
)
答案 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
。顾名思义,该组件当时尚未安装 - 因此您的错误。