réagir natif de cette.setState ne fonctionne pas

Je sais qu'il y a déjà une question similaire mais il n'y a pas de code partagé là-dedans.

Sous navbarChanged() > Si condition, je fais un this.setState. C'est du type HomeTab, mais setState ne semble pas fonctionner.

Des indices/pointeurs?

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 });
  }
}

Et voici mon code render ():

  render() {
    return (
        <NavigatorIOS style={styles.container}
            navigationBarHidden={this.state.isNavBarHidden}
            ref="navigator"
            initialRoute={{
              title: 'Foo',
              component: HomeScreen,
              passProps: { parent: this }
            }}
        />
    )
  }
21
demandé sur Sam Sedighian 2015-06-15 21:19:41

3 réponses

N'appelez pas explicitement render. React fera automatiquement un re-rendu lorsque l'état ou les accessoires changent, donc il n'y a pas besoin de cela. En outre, Où est votre méthode réelle render?

Quant à votre problème, setState est asynchrone et donc essayer de travailler avec l'état directement après un appel setState ne fonctionnera pas car la mise à jour n'aura pas nécessairement été exécutée. Au lieu de cela, vous pouvez utiliser le deuxième argument de setState, qui est un rappel:

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

Cela sera déclenché après que l'État a été défini et après le le composant a été rendu à nouveau.

50
répondu Colin Ramsay 2015-06-16 12:26:37

Au lieu de setState, utilisez state en tant que membre d'instance de la classe es6. la fonction setState peut être appelée plus tard own pour assurer les rendus nécessaires.

  constructor() {
    super()

    this.state = {
      isNavBarHidden: false
    };
  }
4
répondu RKichenama 2016-03-07 19:16:05

Vous pouvez également mettre à jour l'état dans les gestionnaires d'événements et écouter componentWillReceiveProps pour le code que vous devez exécuter après les changements d'état.

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

Je pense que c'est plus optimal que la solution donnée par Colin Ramsay ci-dessus car toute la logique ci-dessus s'exécuterait avant que render ne soit appelé.

1
répondu monish001 2016-09-02 16:14:55