React lädt keine Komponentendaten bei einer Routenparameteränderung oder einer Abfrageänderung neu
Lesezeit: 5 Minuten
Galivan
Ich habe eine “Home”-Komponente mit Links, und wenn Sie auf einen Link klicken, wird die Produktkomponente mit dem Produkt geladen. Ich habe auch eine andere Komponente, die immer sichtbar ist und Links zu den “zuletzt besuchten Produkten” anzeigt.
Diese Links funktionieren nicht, wenn Sie sich auf einer Produktseite befinden. Die URL wird aktualisiert, wenn ich auf den Link klicke, und es erfolgt ein Rendering, aber die Produktkomponente wird nicht mit dem neuen Produkt aktualisiert.
Sie passen also zu den Route path="/products/:product".
Wenn ich mich auf einer Produktseite befinde und versuche, einem ProductHistory-Link zu folgen, wird die URL aktualisiert und gerendert, aber die Komponentendaten ändern sich nicht. Im Codesandbox-Beispiel können Sie die Warnung in der Renderfunktion der Produktkomponenten auskommentieren, um zu sehen, dass sie gerendert wird, wenn Sie dem Link folgen, aber nichts passiert.
Ich weiß nicht, was das Problem ist … Können Sie das Problem erklären und eine Lösung finden? Das wäre toll!
Shubham Khatri
Zusammen mit componentDidMountSie müssen auch die implementieren componentWillReceiveProps oder verwenden getDerivedStateFromProps(ab v16.3.0 aufwärts) in Products Seite, da die gleiche Komponente ist re-rendered mit aktualisiert params und not re-mounted Wenn Sie die Routenparameter ändern, liegt dies daran, dass Parameter als Requisiten an die Komponente übergeben werden und React-Komponenten bei einer Änderung der Requisiten neu gerendert und nicht neu gemountet werden.
BEARBEITEN: ab v16.3.0 verwenden getDerivedStateFromProps Status basierend auf Requisiten festlegen/aktualisieren (keine Notwendigkeit, ihn in zwei verschiedenen Lebenszyklusmethoden anzugeben)
componentWillReceiveProps ist jetzt veraltet. Aber wie kann man das sonst machen?
– Bastian Voigt
12. September 18 um 9:31 Uhr
@BastianVoigt: Sie können die Integration neuer Lebenszyklusmethoden in React +16.3 verwenden getDerivedStateFromProps, componentDidUpdate wie in dieser Antwort beschrieben.
– Arash Khajelou
29. November 18 um 12:13 Uhr
Ich versuchte die getDerivedStateFromProps Lösung. Aber es hat nicht funktioniert. Es scheint, dass die getDerivedStateFromProps feuert nur einmal auf dem Mount.
– Entwicklung
25. Januar 19 um 2:58 Uhr
@arvinsim, nicht wahr, getDerivedStateFromPRops wird sowohl beim anfänglichen Mounten als auch bei jedem anderen Update ausgelöst. Außerdem gab es in 16.4 eine Änderung in dieser API. Ich werde meine Antwort aktualisieren, um diese Änderung einzubeziehen
– Shubham Khatri
25. Januar 19 um 5:30 Uhr
Dies wies mich in die richtige Richtung, danke für die großartige Antwort.
– Moiz
27. April 19 um 5:07 Uhr
Prakasch S
Da die Produktkomponente bereits geladen ist, wird sie nicht neu geladen. Sie müssen die neue Produkt-ID in der folgenden Methode der Komponente handhaben
componentWillReceiveProps(nextProps) {
if(nextProps.match.params.name.product == oldProductId){
return;
}else {
//fetchnewProduct and set state to reload
}
Mit der neuesten Version von React (ab 16.3.0)
static getDerivedStateFromProps(nextProps, prevState){
if(nextProps.productID !== prevState.productID){
return { productID: nextProps.productID};
}
else {
return null;
}
}
componentDidUpdate(prevProps, prevState) {
if(prevProps.productID !== this.state.productID){
//fetchnewProduct and set state to reload
}
}
ComponentWillReceiveProps ist ebenfalls veraltet und gilt jetzt als unsicher … gibt es eine andere Möglichkeit, dies zu tun?
– Bastian Voigt
12. September 18 um 9:32 Uhr
@BastianVoigt es sollte prevProps sein, da componentDidUpdate aufgerufen wird, nachdem sich die Props geändert haben, was die gleichen nextProps sein werden, die wir in getDerivedStateFromProps festgelegt hatten.
– Prakasch S
14. September 18 um 16:17 Uhr
Richtig, aber ich möchte neu laden, wenn sich die aktuelle Produkt-ID (this.props.productID) von der in meinem Zustand unterscheidet, meinst du nicht?
– Bastian Voigt
15. September 18 um 19:37 Uhr
@BastianVoigt. Genau das tut die obige Bedingung. Die aktuelle Produkt-ID (this.props.producID) wird eine neue Produkt-ID haben, die wir in der Zustandsvariablen angegeben haben. Wenn wir das vergleichen, dann wird es immer gleich sein
– Prakasch S
17. September 18 um 3:36 Uhr
Obwohl alle oben genannten Möglichkeiten funktionieren, sehe ich keinen Sinn für die Verwendung getDerivedStateFromProps. Basierend auf React-Dokumenten: “Wenn Sie einige Daten nur dann neu berechnen möchten, wenn sich eine Requisite ändert, verwenden Sie stattdessen einen Memoisierungshelfer”.
Hier würde ich stattdessen vorschlagen, einfach zu verwenden componentDidUpdate zusammen mit dem Ändern der Component zu PureComponenet.
Unter Bezugnahme auf React-Dokumente, PureComponenets Rendert nur neu, wenn sich mindestens ein Zustand oder Prop-Wert ändert. Die Änderung wird bestimmt, indem ein flacher Vergleich von Zustands- und Prop-Schlüsseln durchgeführt wird.
componentDidUpdate = (prevProps) => {
if(this.props.match.params.id !== prevProps.match.params.id ) {
// fetch the new product based and set it to the state of the component
};
};
Bitte beachte, dass das Obige nur funktioniert, wenn du die Komponente in PureComponent änderst, und du sie natürlich aus React importieren musst.
In meinem Fall funktioniert es auch für normale Komponenten.
– Siddharth Gharge
8. Dezember 19 um 16:04 Uhr
Wenn Sie den Status in Ihrer Komponente nicht beibehalten, können Sie verwenden componentDidUpdate ohne die Notwendigkeit getDerivedStateFromProps: