2015-11-19 82 views
2

我有一段觸發警告的代碼(代碼應該登錄到REST並關閉活動指示器)。我不明白我的組件是如何被卸載的,因爲我在button button上綁定了LoginPressed,所有可能的掛載都已經完成。請幫我擺脫它,並瞭解警告的原因...
UPD:感謝評論我發現組件被卸載和componentWillUnmount被調用...但我不明白爲什麼和什麼時候它正在發生的事情...React Native,「卸載組件上的setState()」警告

「警告:的setState(...):只能更新一安裝或安裝 組件這通常意味着你卸載的 組件調用的setState()這是一個NO-請檢查未定義的 組件的代碼。「

這裏是我的代碼,警告是由第二setState觸發:

onLoginPressed(){ 
    console.log('Attempted to login with: '+this.state.username); 
    this.setState({showProgress: true}); 

    AuthService.login({ 
     login: this.state.username, 
     password: this.state.password 
    }, (results)=> { 
     this.setState(Object.assign({ // have to create a solid Object with all states to be changed at once 
     showProgress: false // turning off ActivityIndicator 
     }, results)); 

     if(results.success && this.props.onLogin){ 
     this.props.onLogin(); // Yey! We logged in! Let's move to the next View 
     } 
    }); 
    } 

... AuthService.js:

login (creds, callback) { 
    fetch(CFG.AUTH_URL) 
     .then((response)=> { 
     if((response.status >= 200) && (response.status < 300)){ 
      return response.json(); 
     } 
     throw { 
      serverError: (response.status == 500) || (response.status == 501), 
      unknownError: (response.status != 500) || (response.status != 501) 
     }; 
     }) 
     .then((result)=> { 
      AsyncStorage.multiSet([ // Have to save login+password and session_hash for later use... 
      [authKey, JSON.stringify(creds)], 
      [sessionKey, result.data.session_hash] 
      ], (err)=> { 
      if (err) throw err; 
      }); 
      return callback({success: true}); 
     } 
     }) 
     .catch((err)=> { 
     return callback(err); 
     }); 
    }// end of login 
+0

添加'componentWillUnmount'並檢查是否以及爲什麼它實際卸載。 – zerkms

+0

謝謝。但是我不明白爲什麼它實際上沒有被卸載......在調用堆棧出演沒有幫助,因爲我只是不明白髮生了什麼。組件更新和比,卸載...也許有一種mixins或代碼示例,以獲得更多的信息發生了什麼? –

回答

4

ФедорУсаков,我就遇到了這個問題,以及。我發現由於在回調函數AuthService.login()中設置了狀態,組件被重新渲染。與setState(在這種情況下)的問題:

沒有來電的同步運行的保證SETSTATE ,呼叫可能會分批進行性能提升。

從陣營文檔

我的猜測是,國家沒有被立即設置,然後this.props.onLogin()被調用。這可以在狀態可以設置之前卸載組件,並且瞧,警告

爲了讓我工作,我刪除了條件和onLogin()的調用,並在Login類中添加了shouldComponentUpdate()方法。在shouldComponentUpdate()我放置了刪除的條件和調用。像這樣:

onLoginButtonPress() { 
    // some code 

    AuthService.login({ 
     username: this.state.username, 
     password: this.state.password 
    }, (results) => { 
     this.setState({ 
      ...results, 
      showProgress: false 
     }); 
    }); 
} 

shouldComponentUpdate() { 
    if (this.state.loginSuccess && this.props.onLogin) { 
     this.props.onLogin(); 
    } 
    return true; 
} 

這可以確保國家已定,該組件然後重新呈現因爲this.state.loginSuccess現在是true,則調用this.props.onLogin()導致Login卸載。