2015-06-15 80 views
17

我知道已經有類似的問題,但沒有代碼共享。react-native this.setState not working

根據navbarChanged()>如果條件,我正在做一個this.setState。這是HomeTab類型,但setState似乎沒有工作。

任何線索/指針?

class HomeTab extends React.Component { 
    constructor() { 
    super() 

    this.setState({ 
     isNavBarHidden: false 
    }); 
    } 

    updatePosition(lastPosition) { 
    } 

    navbarChanged() { 
    console.log("received navbar changed event", AppStore.navbarVisible()); 

    if (AppStore.navbarVisible()) { 
     StatusBarIOS.setHidden(false) 
     this.setState({ isNavBarHidden: false}) 
     // this.state.isNavbarHidden is still true here 
     this.render(); 
    } 
    else { 
     StatusBarIOS.setHidden(true); 
     this.setState({ isNavBarHidden: true}); 
     this.render(); 
    } 
    } 

    componentDidMount() { 
    AppStore.addNavbarChangeListener(this.navbarChanged.bind(this)); 
    } 

    componentWillMount() { 
    StatusBarIOS.setHidden(false) 
    this.setState({ isNavBarHidden: false }); 
    } 
} 

這是我的渲染()代碼:

render() { 
    return (
     <NavigatorIOS style={styles.container} 
      navigationBarHidden={this.state.isNavBarHidden} 
      ref="navigator" 
      initialRoute={{ 
       title: 'Foo', 
       component: HomeScreen, 
       passProps: { parent: this } 
      }} 
     /> 
    ) 
    } 

回答

43

不要顯式調用render。當狀態或道具改變時,React會自動重新渲染,所以不需要這個。另外,您的實際render方法在哪裏?

至於你的問題,setState是異步的,所以試圖在setState調用後直接使用狀態不會工作,因爲更新不一定會運行。相反,你可以使用第二個參數setState這是一個回調:

this.setState({ myVal: 'newVal'}, function() { 
    // do something with new state 
}); 

狀態的設置後,這將被觸發,之後組件已重新呈現。

+1

非常感謝您的回答。異步的'setState'回答了這個問題。我用我的渲染方法()更新了我的代碼。我將擺脫render();你的建議是有道理的。儘管爲什麼我的導航欄不顯示(但標題欄是),我仍然感到困惑。 – Abdo

+1

WOW謝謝 - 我不知道甚至一遍又一遍地閱讀setState是異步的文檔 - 很多在線內容都表示在調用這個UI之後UI會呈現出來 - 它不會立即顯示出來,而且您的回答大量幫助我。謝謝 – landed

4

而不是setState,使用狀態作爲es6類的實例成員。函數setState可以稍後調用以確保必要的重新呈現。

constructor() { 
    super() 

    this.state = { 
     isNavBarHidden: false 
    }; 
    } 
0

您也可以更新事件處理器的狀態,並聽取componentWillReceiveProps爲你需要的狀態變化後運行的代碼。

componentWillReceiveProps(nextProps,nextState){ 
    if(this.state.myVar === nextState.myVar){ 
    return; 
    } 
    // TODO perform changes on state change 
} 

我認爲這是比Colin Ramsay上述所有上述邏輯將render運行之前被調用給出的解決方案更優化。