Hier ist das Problem: Ich versuche, 2 Funktionen auf Knopfdruck aufzurufen. Beide Funktionen aktualisieren den Status (ich verwende den useState-Hook). Die erste Funktion aktualisiert den Wert1 korrekt auf 'neue 1', aber nach 1s (setTimeout) wird die zweite Funktion ausgelöst und der Wert 2 in 'neue 2' geändert, ABER! Der Wert1 wird auf '1' zurückgesetzt. Warum passiert dies? Danke im Voraus!
import React, { useState } from "react";
const Test = () => {
const [state, setState] = useState({
value1: "1",
value2: "2"
});
const changeValue1 = () => {
setState({ ...state, value1: "new 1" });
};
const changeValue2 = () => {
setState({ ...state, value2: "new 2" });
};
return (
<>
<button
onClick={() => {
changeValue1();
setTimeout(changeValue2, 1000);
}}
>
CHANGE BOTH
</button>
<h1>{state.value1}</h1>
<h1>{state.value2}</h1>
</>
);
};
export default Test;
javascript
reactjs
react-hooks
Bartek
quelle
quelle
changeValue2
?useState
oder stattdessen verwendenuseReducer
.const [state, ...]
, und dann im Setter darauf verweisen ... Es wird immer den gleichen Zustand verwenden.useState
Aufrufe, einen für jede "Variable".Antworten:
Willkommen in der Schließungshölle . Dieses Problem tritt auf, weil , wenn
setState
aufgerufen,state
eine neue Speicher - Referenz bekommt, aber die FunktionenchangeValue1
undchangeValue2
aufgrund der Schließung, halten die alte anfänglichestate
Referenz.Eine Lösung, um sicherzustellen, dass der aktuelle Status
setState
vonchangeValue1
undchangeValue2
abgerufen wird, besteht in der Verwendung eines Rückrufs (mit dem vorherigen Status als Parameter):Eine breitere Diskussion zu diesem Abschlussproblem finden Sie hier und hier .
quelle
Ihre Funktionen sollten folgendermaßen aussehen:
So stellen Sie sicher, dass im aktuellen Status keine vorhandene Eigenschaft fehlt, indem Sie den vorherigen Status verwenden, wenn die Aktion ausgelöst wird. So vermeiden Sie auch, dass Sie Schließungen verwalten müssen.
quelle
Wenn
changeValue2
es aufgerufen wird, wird der Anfangszustand gehalten, so dass der Zustand in den Anfangszustand zurückkehrt und dann dievalue2
Eigenschaft geschrieben wird.Wenn das nächste Mal danach
changeValue2
aufgerufen wird, enthält es den Status{value1: "1", value2: "new 2"}
, sodass dievalue1
Eigenschaft überschrieben wird.Sie benötigen eine Pfeilfunktion für den
setState
Parameter.quelle
Was passiert ist, dass beide
changeValue1
undchangeValue2
den Status aus dem Render sehen, in dem sie erstellt wurden. Wenn Ihre Komponente zum ersten Mal gerendert wird, sehen diese beiden Funktionen:Wenn Sie auf die Schaltfläche klicken,
changeValue1
wird zuerst aufgerufen und der Status wird{value1: "new1", value2: "2"}
wie erwartet geändert .Jetzt wird nach 1 Sekunde
changeValue2
aufgerufen, aber diese Funktion sieht immer noch den Anfangszustand ({value1; "1", value2: "2"}
). Wenn diese Funktion den Zustand auf folgende Weise aktualisiert:setState({ ...state, value2: "new 2" });
Sie sehen am Ende :
{value1; "1", value2: "new2"}
.Quelle
quelle