2017-11-17 60 views
1

這是完全錯誤:警告:只能更新一安裝或安裝組件

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>

回答

1

直到您將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這個例子是使用承諾 –

0

它看起來就像你在componentWillMount稱爲this.setState。顧名思義,組件當時尚未安裝 - 因此是您的錯誤。

+0

如何在頁面呈現任何內容之前設置狀態? –

+0

如果在渲染頁面之前設置了狀態,則可能需要的是「props」。將這個組件包裝在一個更高階的組件中,讓HOC調用API調用,並將結果'({redirect:true})'作爲'props'傳遞給子組件。 – wrayjs

相關問題