【问题标题】:react-native this.setState not workingreact-native this.setState 不起作用
【发布时间】:2015-06-15 18:19:41
【问题描述】:

我知道已经有一个类似的问题,但那里没有共享代码。

navbarChanged() > if 条件下,我正在做一个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() 代码:

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

【问题讨论】:

    标签: reactjs react-native


    【解决方案1】:

    不要显式调用render。当 state 或 props 改变时,React 会自动重新渲染,所以没有必要这样做。另外,您实际的render 方法在哪里?

    至于您的问题,setState 是异步的,因此尝试在 setState 调用之后直接使用状态将不起作用,因为更新不一定已经运行。相反,您可以使用 setState 的第二个参数,这是一个回调:

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

    这将在设置状态和重新渲染组件后触发。

    【讨论】:

    • 非常感谢您的回答。 setState 异步回答了这个问题。我已经用我的渲染方法()更新了我的代码。我将摆脱 render() ;你的建议是有道理的。尽管我的导航栏没有显示回来(但标题栏显示),但我仍然感到困惑。
    • 哇,谢谢 - 我什至不知道一遍又一遍地阅读 setState 是异步的文档 - 远非如此,许多在线 tuts 说 UI 会在调用它后呈现 - 它不会立即和你的答案极大地帮助了我。谢谢
    【解决方案2】:

    使用 state 作为 es6 类的实例成员,而不是 setState。以后可以自己调用函数 setState 以确保必要的重新渲染。

      constructor() {
        super()
    
        this.state = {
          isNavBarHidden: false
        };
      }
    

    【讨论】:

      【解决方案3】:

      您还可以在 eventHandlers 中更新状态并收听componentWillReceiveProps 以获取在状态更改后需要运行的代码。

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

      我认为它比上面Colin Ramsay 给出的解决方案更优化,因为上述所有逻辑都会在render 被调用之前运行。

      【讨论】:

      • 这个生命周期方法现在已被弃用我相信,getDerivedStateFromProps 通常被推荐作为替代品,但在这种情况下这不起作用,因为它是一个 static 生命周期方法并且您正在引用 this在里面。
      猜你喜欢
      • 1970-01-01
      • 2021-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多