React lädt keine Komponentendaten bei einer Routenparameteränderung oder einer Abfrageänderung neu

Lesezeit: 5 Minuten

React ladt keine Komponentendaten bei einer Routenparameteranderung oder einer Abfrageanderung
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.

Siehe dieses Beispiel:
Codesandbox-Beispiel

Hier sind die Routen in index.js:

<BrowserRouter>
  <div>
    <Route
      exact
      path="https://stackoverflow.com/"
      render={props => <Home products={this.state.products} />}
    />

    <Route path="/products/:product" render={props => <Product {...props} />} />

    <Route path="https://stackoverflow.com/" render={() => <ProductHistory />} />

    <Link to="https://stackoverflow.com/">to Home</Link>
  </div>
</BrowserRouter>;

Die Links in ProductHistory sehen so aus:

<Link to={`/products/${product.product_id}`}> {product.name}</Link>

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!

1643042106 51 React ladt keine Komponentendaten bei einer Routenparameteranderung oder einer Abfrageanderung
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)

static getDerivedStateFromProps(nextProps, prevState) {
   if (nextProps.match.params.product !== prevState.currentProductId){
      const currentProductId = nextProps.match.params.product
      const result = productlist.products.filter(obj => {

        return obj.id === currentProductId;

      })
     return {

        product: result[0],
        currentId: currentProductId,
        result

      }
  }
  return null;
}

Vor v16.3.0 würden Sie „componentWillReceiveProps“ verwenden

componentWillReceiveProps(nextProps) {
    if (nextProps.match.params.product !== this.props.match.params.product) {
      const currentProductId = nextProps.match.params.product
      const result = productlist.products.filter(obj => {

        return obj.id === currentProductId;

      })
      this.setState({

        product: result[0],
        currentId: currentProductId,
        result

      })
    }
  }

Arbeitscodesandbox

  • 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

React ladt keine Komponentendaten bei einer Routenparameteranderung oder einer Abfrageanderung
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:

  componentDidUpdate(prevProps) {
    const { match: { params: { value } } } = this.props
    if (prevProps.match.params.value !== value){
      doSomething(this.props.match.params.value)
    }
  }

.

620480cookie-checkReact lädt keine Komponentendaten bei einer Routenparameteränderung oder einer Abfrageänderung neu

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy