2017-04-10 5 views
7

Ich habe Tyler McGinnis curriculum implementieren, um zu lernen reagieren.Lifecycle-KomponenteWillReceiveProps wird mehrmals aufgerufen

Es ist eine Wetter App. Und ich habe Probleme, ein seltsames Verhalten zu debuggen. Ich bin mir ziemlich sicher, dass es etwas Dummes ist, was ich tue, oder dass ich eine Information Information verpasst hätte.

SearchContainer ist ein ParentContainer,

var React = require("react"); 
var Search = require("../components/Search"); 

var SearchContainer = React.createClass({ 
    propTypes: { 
    formType: React.PropTypes.string 
    }, 
    contextTypes: { 
    router: React.PropTypes.object.isRequired 
    }, 
    getDefaultProps: function() { 
    return { 
     formType: "form" 
    } 
    }, 
    getInitialState: function() { 
    return { 
     city: "" 
    } 
    }, 
    handleSearchSubmit: function(e) { 
    e.preventDefault(); 
    this.context.router.push('/forecast/' + this.state.city); 
    }, 
    handleCityChange: function(e) { 
    this.setState({ 
     city: e.target.value 
    }); 
    }, 
    render() { 
    return (
     <Search 
     formType={this.props.formType} 
     city={this.state.city} 
     onCityChange={this.handleCityChange} 
     onSearchSubmit={this.handleSearchSubmit}/> 
    ); 
    } 
}) 

module.exports = SearchContainer; 

SearchContainer Kontext ändert und schaltet auf ForecastContainer,

var React = require("react"); 

var Forecast = require("../components/Forecast"); 
var Api = require("../helpers/Api"); 

var ForecastContainer = React.createClass({ 
    getInitialState: function() { 
    return { 
     isLoading: true, 
     data: [] 
    } 
    }, 
    makeRequest: function(city) { 
    this.setState({ 
      isLoading: true, 
    }); 
    Api.getDayForecast(city).then(function(data) { 
     this.setState({ 
      isLoading: false, 
      data: data.data.list 
     }); 
    }.bind(this)); 
    }, 
    componentDidMount: function() { 
    this.makeRequest(this.props.params.city); 
    }, 
    componentWillReceiveProps: function(newProps) { 
    this.makeRequest(newProps.params.city); 
    }, 
    render() { 
    return (
     <Forecast isLoading={this.state.isLoading} data={this.state.data} /> 
    ) 
    } 
}); 

module.exports = ForecastContainer; 

Hier, componentWillReceiveProps zweimal aufgerufen wird. Ich verstehe nicht warum. Technisch sollte es nur einmal aufgerufen werden. Ich aktualisiere Zustand in MakeRequest Methode. Es wird zum zweiten Mal nach der Zustandsänderung aufgerufen.

Ich füge auch Screenshots zum besseren Verständnis des Anwendungsflusses bei.

enter image description here

Update:

Ich war mit React-Router Version 3.0.3. Downgrade auf 2.0.0 behebt es. Was um so merkwürdiger ist.

+0

Also habe ich gerade react-router-Version auf 2.0.0 herabgestuft und jetzt wird der componentWillReceiveProps einmal aufgerufen. Das ist merkwürdig. Hat es etwas mit dem neuen React-Router zu tun? – kishanio

Antwort

10

kann ich dir nicht sagen warum es wird zweimal aufgerufen, aber ich kann Ihnen sagen, dass es egal sein sollte. Das Problem ist, dass Sie nicht die Requisiten für das, was sich geändert hat, vergleichen. Wenn Sie das tun, verhält sich der Code, wie Sie wollen:

componentWillReceiveProps: function(newProps) { 
    if (newProps.params.city !== this.props.params.city) { 
    this.makeRequest(newProps.params.city); 
    } 
}, 

Siehe auch die offizielle ReactJS Dokumentation, in dem es heißt (Hervorhebung von mir): https://facebook.github.io/react/docs/react-component.html#componentwillreceiveprops

Beachten Sie, dass diese Methode kann anrufen Reagieren auch wenn die Requisiten nicht geändert haben, also stellen Sie sicher, die aktuellen und nächsten Werte zu vergleichen, wenn Sie nur Änderungen ändern möchten. Dies kann auftreten, wenn die übergeordnete Komponente Ihre Komponente zum erneuten Rendern veranlasst.

+0

Oh ja, das habe ich mir gedacht. Ich habe einen Vergleich gemacht und damit weitergemacht. Ich weiß nicht, warum ich so nervös bin. Es ist einfach witzig, wie es auch funktioniert, wenn man die react-router-Version herunterlädt. – kishanio

+0

@kishanio Meine Vermutung ist, dass der neue Router aus irgendeinem Grund eines der in der Dokumentation erwähnten Rendern verursacht. Es ist jedoch * erlaubt * Verhalten und kein Bug, also würde ich zurück zu Router v3.0.3 gehen, wenn es keinen zwingenden Grund gibt, dies nicht zu tun. – Lucero

Verwandte Themen