2015-08-28 12 views
28

Ich arbeite an einer React-Anwendung, die den React-Router verwendet. Ich habe eine Projekt-Seite, die eine URL hat, wie folgt:Komponente wird nicht neu installiert, wenn sich die Routenparameter ändern

myapplication.com/project/unique-project-id 

Wenn die Projektkomponente lädt, ich Auslöser für dieses Projekt eine Datenanforderung aus dem componentDidMount Ereignisse. Ich laufe jetzt in ein Problem, bei dem, wenn ich direkt zwischen zwei Projekten wechseln, so dass nur die ID Änderungen wie diese ...

myapplication.com/project/982378632 
myapplication.com/project/782387223 
myapplication.com/project/198731289 

componentDidMount nicht wieder ausgelöst, so dass die Daten nicht aktualisiert wird. Gibt es ein anderes Lebenszyklusereignis, das ich verwenden sollte, um meine Datenanforderung auszulösen, oder eine andere Strategie, um dieses Problem anzugehen?

+1

Konnten Sie Ihren Komponentencode bekannt geben? – Pcriulan

Antwort

33

Wenn der Link auf die gleiche Route mit nur einem anderen Parameter verweist, wird er nicht neu gemountet, sondern erhält stattdessen neue Requisiten. So können Sie die componentWillReceiveProps(newProps) Funktion verwenden und nach newProps.params.projectId suchen.

Wenn Sie versuchen, Daten zu laden, würde ich empfehlen, die Daten abzurufen, bevor der Router die Übereinstimmung mit statischen Methoden für die Komponente verarbeitet. Schau dir dieses Beispiel an. React Router Mega Demo. Auf diese Weise würde die Komponente die Daten laden und automatisch aktualisieren, wenn sich die Routenparameter ändern, ohne auf componentWillReceiveProps angewiesen zu sein.

+0

Danke. Ich konnte mit componentWillReceiveProps arbeiten. Ich verstehe den React Router Mega Demo-Datenfluss immer noch nicht wirklich. Ich sehe die statischen fetchData für einige Komponenten definiert. Wie werden diese Statiken vom Router Client aufgerufen? – Constellates

+0

Große Frage. Überprüfen Sie die Datei client.js und die Datei server.js. Während des Laufs des Routers rufen sie die Datei fetchData.js auf und übergeben ihr den 'state'. Es ist zunächst etwas verwirrend, wird dann aber etwas klarer. –

+0

Kommen einige Monate später, und da ich sehr unerfahren bin, habe ich Schwierigkeiten, die Beispiele mit den Änderungen zu react-router mit Release 1.0 zu aktualisieren - ist es jetzt noch möglich, dass Router.run durch render ersetzt wurde ( {routes }}, el) - können wir das Holen noch tun, bevor der Fräser das Match behandelt? – theTechnaddict

21

Wenn Sie eine Komponenten-Remount-Funktion benötigen, wenn sich die Route ändert, können Sie einen eindeutigen Schlüssel an das Schlüsselattribut Ihrer Komponente übergeben (der Schlüssel ist Ihrem Pfad/Route zugeordnet). Jedes Mal, wenn sich die Route ändert, ändert sich auch der Schlüssel, welcher die React-Komponente zum Unmount/Remount auslöst. Ich habe die Idee von this answer

+0

das ist absolut großartig, danke! – davnicwil

+0

Danke. Dies sollte akzeptiert werden Antwort –

0

react-router ist kaputt, weil es Komponenten bei jeder Standortänderung neu mounten müssen.

ich es geschafft, obwohl eine Lösung für diesen Fehler zu finden:

https://github.com/ReactTraining/react-router/issues/1982#issuecomment-275346314

Kurz (den Link oben für weitere Informationen siehe)

<Router createElement={ (component, props) => 
{ 
    const { location } = props 
    const key = `${location.pathname}${location.search}` 
    props = { ...props, key } 
    return React.createElement(component, props) 
} }/> 

Dies wird es auf jede URL machen Remount Änderung

4

Sie müssen sich darüber im Klaren sein, dass eine Änderung der Route keine Seitenaktualisierung verursacht, Sie müssen selbst damit umgehen.

import theThingsYouNeed from './whereYouFindThem' 

export default class Project extends React.Component { 

    componentWillMount() { 

     this.state = { 
      id: this.props.router.params.id 
     } 

     // fire action to update redux project store 
     this.props.dispatch(fetchProject(this.props.router.params.id)) 
    } 

    componentDidUpdate(prevProps, prevState) { 
     /** 
     * this is the initial render 
     * without a previous prop change 
     */ 
     if(prevProps == undefined) { 
      return false 
     } 

     /** 
     * new Project in town ? 
     */ 
     if (this.state.id != this.props.router.params.id) { 
      this.props.dispatch(fetchProject(this.props.router.params.id)) 
      this.setState({id: this.props.router.params.id}) 
     } 

    } 

    render() { <Project .../> } 
} 
+0

Danke, diese Lösung funktioniert für mich. Aber mein eslint Einstellung beschweren sich darüber: https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-did-update-set-state.md Worüber denken Sie darüber nach Dies? – Konekoya

+0

Ja, das ist eigentlich keine Best Practice, tut mir leid, nach dem Versand des "fetchProject" wird dein Reducer sowieso deine Requisiten updaten, ich habe das nur benutzt, um meinen Standpunkt klar zu machen – chickenchilli

+0

Hi chickenchilli, Ich bin eigentlich immer noch stecken in diesem ... haben Sie andere Vorschläge oder empfohlene Tutorials? Oder ich bleibe vorerst bei deiner Lösung. Danke für Ihre Hilfe! – Konekoya

Verwandte Themen