React.useState lädt den Status von Requisiten nicht neu

95

Ich erwarte, dass der Status beim Ändern der Requisiten neu geladen wird, aber dies funktioniert nicht und die userVariable wird beim nächsten useStateAufruf nicht aktualisiert . Was ist falsch?

function Avatar(props) {
  const [user, setUser] = React.useState({...props.user});
  return user.avatar ? 
         (<img src={user.avatar}/>)
        : (<p>Loading...</p>);
}

Codepen

Vitalyster
quelle

Antworten:

211

Das an useState übergebene Argument ist der Anfangsstatus, ähnlich wie das Festlegen des Status im Konstruktor für eine Klassenkomponente, und wird nicht zum Aktualisieren des Status beim erneuten Rendern verwendet

Wenn Sie den Status beim Requisitenwechsel aktualisieren möchten, verwenden Sie den useEffectHook

function Avatar(props) {
  const [user, setUser] = React.useState({...props.user});

  React.useEffect(() => {
      setUser(props.user);
  }, [props.user])

  return user.avatar ? 
         (<img src={user.avatar}/>)
        : (<p>Loading...</p>);
}

Arbeitsdemo

Shubham Khatri
quelle
18
Wenn Sie den Anfangszustand im Konstruktor festlegen, ist klar, dass der Konstruktor bei der Erstellung der Klasseninstanz einmal aufgerufen wird. Bei Hooks sieht es so aus, als würde useState jedes Mal beim Funktionsaufruf aufgerufen und jedes Mal, wenn der Status initialisiert werden soll, aber dort passiert etwas ungeklärte "Magie".
Vitalyster
Vielleicht wirft
Shubham Khatri
Wenn Sie Requisiten in den Status zusammenführen müssen, stecken Sie in einer Endlosschleife fest, wenn Sie die App create-react-app verwenden, für die der Status im Abhängigkeitsarray sein muss
user210757
2
Dies führt dazu, dass der Ausgangszustand zweimal eingestellt wird, was ziemlich ärgerlich ist. Ich frage mich, ob Sie den Anfangszustand auf null setzen und dann verwenden können React.useEffect, um den Anfangszustand jedes Mal festzulegen.
CMCDragonkai
2
Dies funktioniert nicht, wenn der Status auch das Rendern steuert. Ich habe eine funktionale Komponente, die basierend auf Requisiten und basierend auf dem Status rendert. Wenn der Status die Komponente anweist, zu rendern, weil sie sich geändert hat, wird useEffect ausgeführt und setzt den Status auf den Standardwert zurück. Das ist wirklich schlechtes Design von ihrer Seite.
Greg Veres
1

Funktionskomponenten, mit denen wir useStateAnfangswerte für unsere Variable festlegen. Wenn wir den Anfangswert über Requisiten übergeben, wird immer der gleiche Anfangswert festgelegt, bis Sie keinen useEffectHook verwenden.

Zum Beispiel wird Ihr Fall Ihren Job machen

 React.useEffect(() => {
      setUser(props.user);
  }, [props.user])

Die an useEffect übergebene Funktion wird ausgeführt, nachdem das Rendern auf dem Bildschirm festgeschrieben wurde.

Standardmäßig werden Effekte nach jedem abgeschlossenen Rendering ausgeführt. Sie können sie jedoch nur dann auslösen, wenn sich bestimmte Werte geändert haben.

React.useEffect(FunctionYouWantToRunAfterEveryRender)

Wenn Sie nur ein Argument an useEffect übergeben, wird diese Methode nach jedem Rendern ausgeführt. Sie können entscheiden, wann dies FunctionYouWantToRunAfterEveryRenderausgelöst werden soll, indem Sie das zweite Argument an useEffect übergeben

React.useEffect(FunctionYouWantToRunAfterEveryRender, [props.user])

Wie Sie bemerken, übergebe ich [props.user] jetzt useEffectwird diese FunctionYouWantToRunAfterEveryRenderFunktion nur ausgelöst, wenn sie props.usergeändert wird

Ich hoffe, dies hilft Ihrem Verständnis. Lassen Sie mich wissen, wenn Verbesserungen erforderlich sind. Danke

Hanzla Habib
quelle
0

Der übergebene Parameter React.useState()ist nur der Anfangswert für diesen Zustand. React erkennt dies nicht als Änderung des Status, sondern setzt nur den Standardwert. Sie möchten zunächst den Standardstatus festlegen und dann unter bestimmten Bedingungen setUser(newValue)einen Status aufrufen , der als neuer Status erkannt wird, und die Komponente erneut rendern.

Ich würde empfehlen, den Status ohne irgendeine Bedingung zu aktualisieren, um zu verhindern, dass er ständig aktualisiert wird, und daher jedes Mal neu zu rendern, wenn Requisiten empfangen werden. Möglicherweise möchten Sie die Statusfunktionalität auf eine übergeordnete Komponente übertragen und den Status des übergeordneten Elements als Requisite an diesen Avatar weitergeben.

Schläfrig
quelle
-2

Laut der ReactJS-Dokumentation zu Hooks :

Aber was passiert, wenn sich die Requisite eines Freundes ändert, während sich die Komponente auf dem Bildschirm befindet? Unsere Komponente zeigt weiterhin den Online-Status eines anderen Freundes an. Dies ist ein Fehler. Wir würden auch einen Speicherverlust oder Absturz beim Aufheben der Bereitstellung verursachen, da der Abmeldeanruf die falsche Freund-ID verwenden würde.

Ihre einzige Interaktion hier sollte bei einem Requisitenwechsel stattfinden, der anscheinend nicht funktioniert. Sie können (immer noch laut Dokument) ein componentDidUpdate (prevProps) verwenden, um proaktiv alle Aktualisierungen der Requisiten abzufangen.

PS: Ich habe nicht genug Code, um zu beurteilen, aber konnten Sie Benutzer () nicht aktiv in Ihre Avatar (Requisiten) -Funktion setzen?

Mwak
quelle
-12

In der Reaktionswelt sollten Sie in solchen Fällen Ihren Status in der Funktion componentWillRecieveProps (nextProps) aktualisieren.

Sushil Mahajan
quelle
4
Was für die neuesten Versionen von
React