2017-03-22 9 views
0

Ich bin neu in react-router und jetzt habe ich folgende Routen in meiner App:Infinite componentDidUpdate() ruft mit reagieren-Router

<Router history={browserHistory}> 
    <Route path="/" component={MainLayout}> 
     <Route path="/v/:username/:reponame/:page/:perPage" component={Results} /> 
    </Route> 
</Router> 

Wie Sie sehen können, gibt es eine MainLayout Komponente, die eine <input type="text"> enthält, die ist verwendet, um eine Verbindung zu Github API herzustellen und eine Liste der Probleme für ein bestimmtes Repo abzurufen. .

Dann werden die Results Teilschritte in Hier ist der Code dafür componentDidMount() ist:

componentDidMount() { 
    const { 
     username, 
     reponame, 
     page, 
     perPage 
    } = this.props.params; 
    this.sendRequest(username, reponame, page, perPage); 
} 

sendRequests Wesentlichen die ajax Abfrage enthält die Ausgangsdaten für das Abrufen, wonach sie in die Komponente des Zustandes Set wird:

this.state = { 
     data: [], // here 
     lastPage: -1, 
     errorMessage: '' 
    } 

Jetzt funktioniert das ziemlich gut bis zu dem Moment, wenn man den Wert eines input ändern will. Wie ich sehe, wird die Result Komponente nicht unmounten. Stattdessen ruft es componentWillReceiveProps() auf und aktualisiert die vorhandene Komponente. AFAIK ist es sicher, Nebenrufe in componentDidUpdate() durchzuführen, also habe ich gerade den Code oben von componentDidMount() kopiert und es dort eingefügt. Auf diese Weise wird (und es ist absolut vernünftig) componentDidMount() immer und immer wieder aufgerufen.

Die einzige Abhilfe, die ich mit zur Zeit alte und neue Daten in den sendRequest() vergleicht kam selbst und nur setState() in der es beruft, wenn es über deep-equal Paket unterscheidet, so sieht es wie folgt aus:

if (!equal(res, this.state.data)) { 
     this.setState({ 
      ...this.state, 
      data: res, 
      lastPage 
     }); 
    } 

Wird dies als ein gutes Muster angesehen oder gibt es einen besseren Weg, dieses Problem zu lösen?

+0

Sie einen String-Vergleich machen könnte, wenn Sie beide Objekte stringify, sollte dies schneller sein. Aber wenn Sie nur Daten in dem Zustand vergleichen, dann würde es ausreichen, 'this.setState ({data: res})' aufzurufen – Raulucco

Antwort