Ich probiere die neuen React Hooks aus und habe eine Clock-Komponente mit einem Zähler, der sich jede Sekunde erhöhen soll. Der Wert steigt jedoch nicht über eins an.
function Clock() {
const [time, setTime] = React.useState(0);
React.useEffect(() => {
const timer = window.setInterval(() => {
setTime(time + 1);
}, 1000);
return () => {
window.clearInterval(timer);
};
}, []);
return (
<div>Seconds: {time}</div>
);
}
ReactDOM.render(<Clock />, document.querySelector('#app'));
<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>
<div id="app"></div>
quelle
useEffect
Die Funktion wird beim Einhängen von Komponenten nur einmal ausgewertet, wenn eine leere Eingabeliste bereitgestellt wird.Eine Alternative dazu
setInterval
besteht darin, beisetTimeout
jeder Aktualisierung des Status ein neues Intervall festzulegen:Die Auswirkungen auf die Leistung von
setTimeout
sind unbedeutend und können im Allgemeinen ignoriert werden. Sofern die Komponente nicht zeitempfindlich gegenüber dem Punkt ist, an dem neu eingestellte Zeitüberschreitungen unerwünschte Auswirkungen haben, sind sowohlsetInterval
als auchsetTimeout
Ansätze akzeptabel.quelle
Wie andere bereits betont haben, besteht das Problem darin, dass
useState
nur einmal aufgerufen wird (deps = []
um das Intervall festzulegen:Jedes Mal, wenn ein
setInterval
Häkchen gesetzt ist, wird tatsächlich aufgerufensetTime(time + 1)
, estime
wird jedoch immer der Wert beibehalten, den es ursprünglich hatte, als dersetInterval
Rückruf (Abschluss) definiert wurde.Sie können die alternative Form des
useState
Setters verwenden und einen Rückruf anstelle des tatsächlichen Werts bereitstellen, den Sie einstellen möchten (genau wie beisetState
):Aber ich würde Sie ermutigen, Ihren eigenen
useInterval
Hook zu erstellen, damit Sie Ihren Code durchsetInterval
deklarative Verwendung TROCKNEN und vereinfachen können , wie Dan Abramov hier in Making setInterval Declarative with React Hooks vorschlägt :Abgesehen davon, dass Sie einfacheren und saubereren Code erstellen, können Sie das Intervall automatisch anhalten (und löschen), indem Sie es übergeben,
delay = null
und die Intervall-ID zurückgeben, falls Sie es selbst manuell abbrechen möchten (dies wird in Dans Beiträgen nicht behandelt).Eigentlich könnte dies auch verbessert werden, damit es nicht neu
delay
gestartet wird, wenn es nicht angehalten ist, aber ich denke, für die meisten Anwendungsfälle ist dies gut genug.Wenn Sie nach einer ähnlichen Antwort suchen
setTimeout
und nicht nachsetInterval
, lesen Sie diese: https://stackoverflow.com/a/59274757/3723993 .Sie können auch deklarative Version finden
setTimeout
undsetInterval
,useTimeout
unduseInterval
, sowie ein benutzerdefinierteruseThrottledCallback
in in Typoskript geschrieben Haken https://gist.github.com/Danziger/336e75b6675223ad805a88c2dfdcfd4a .quelle
Eine alternative Lösung wäre die Verwendung
useReducer
, da immer der aktuelle Status übergeben wird.quelle
Gehen Sie wie folgt vor, es funktioniert gut.
quelle
count => count + 1
Rückruf hat bei mir funktioniert, danke!Sagen Sie React React erneut rendern, wenn sich die Zeit ändert. Optischer Ausgang
quelle
count
Änderung gelöscht und zurückgesetzt wird .setTimeout()
bevorzugt wird, wie von EstusDiese Lösungen funktionieren bei mir nicht, weil ich die Variable abrufen und einige Dinge tun muss, um sie nicht nur zu aktualisieren.
Ich bekomme eine Problemumgehung, um den aktualisierten Wert des Hooks mit einem Versprechen zu erhalten
Z.B:
Damit kann ich den Wert innerhalb der setInterval-Funktion wie folgt erhalten
quelle
Wenn jemand eine Warteschlange verwalten muss
Nehmen wir an, Sie benachrichtigen Benachrichtigungen mit einem Intervall von 3 Sekunden (First In, First Out) und können jederzeit neue Nachrichten senden.
Beispiel für Codesandbox.
quelle