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

问题描述:

这是完全错误:警告:只能更新一安装或安装组件

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>

直到您将gapi.load方法移动到更高的组件中时,您将始终看到该flash。它所调用的函数是一个承诺,这意味着您的组件将在请求该函数时继续渲染。我会将这一块移动到它自己的组件的高一级,并让您的登录页面成为该组件的子项。

编辑:

下面是一个例子:

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> 
     ) 
    } 
} 

所以,现在的<SignIn />组件将不会被渲染后,才将已授权的请求已经完成,并且用户不会被重定向。

+0

Np,很高兴你能工作! –

+0

这不与承诺 – shorif2000

+0

@ shorif2000这个例子是使用承诺 –

它看起来就像你在componentWillMount称为this.setState。顾名思义,组件当时尚未安装 - 因此是您的错误。

+0

如何在页面呈现任何内容之前设置状态? –

+0

如果在渲染页面之前设置了状态,则可能需要的是“props”。将这个组件包装在一个更高阶的组件中,让HOC调用API调用,并将结果'({redirect:true})'作为'props'传递给子组件。 – wrayjs