2015-06-15 78 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运行之前被调用给出的解决方案更优化。