2015-06-15 9 views
17

ich weiß, gibt es bereits eine ähnliche Frage, aber es gibt keinen Code in dort geteilt.reagieren-native this.setState nicht funktioniert

Unter navbarChanged()> wenn Bedingung, mache ich eine this.setState. Dies ist vom Typ HomeTab aber setState scheint nicht zu funktionieren.

Irgendwelche Hinweise/Zeiger?

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

Und hier ist mein render() Code:

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

Antwort

43

nicht explizit render nennen. Reagieren wird automatisch neu gerendert, wenn sich der Status oder die Requisiten ändern, also ist dies nicht nötig. Wo ist Ihre aktuelle render Methode?

Wie für Ihr Problem gut, setState ist asynchron und so versuchen, mit dem Zustand direkt nach einem setState Aufruf funktioniert nicht funktionieren, da das Update nicht unbedingt ausgeführt haben. Stattdessen können Sie das zweite Argument zu setState verwenden, die ein Rückruf:

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

Diese wird ausgelöst, nachdem Zustand gesetzt wurde und nachdem die Komponente neu gerendert wurde.

+1

Vielen Dank für Ihre Antwort. 'setState' ist asynchron, beantwortet diese Frage. Ich habe meinen Code mit meiner Rendermethode() aktualisiert. Ich werde loswerden render(); Was du vorgeschlagen hast, macht Sinn. Ich bin immer noch verwirrt, obwohl meine Navigationsleiste nicht angezeigt wird (aber die Titelleiste ist). – Abdo

+1

WOW Dank - ich hatte auch keine Ahnung, das Lesen über und über die Dokumentation, die setState async ist - ganz im Gegenteil viele Online-tuts sagen, dass die Benutzeroberfläche nach dem Aufruf dieser machen wird - es funktioniert nicht sofort und Ihre Antwort hat mir geholfen, massiv. Vielen Dank – landed

4

Statt setState, Zustand als Instanz Mitglied der ES6 Klasse verwenden. Die Funktion setState kann später selbst aufgerufen werden, um notwendige Neu-Renderings zu gewährleisten.

constructor() { 
    super() 

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

Sie können auch den Zustand, in den Eventhandler aktualisieren und zu componentWillReceiveProps für Code hören, dass Sie nach den Zustandsänderungen ausgeführt werden müssen.

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

Ich denke, es als Lösung von Colin Ramsay oben wie alle obigen Logik vor render liefe wird aufgerufen gegeben mehr optimal ist.