Erstellen Sie eine Stoppuhr mit redux
Ich habe versucht, eine Stoppuhr in reagieren und redux. Ich habe Schwierigkeiten, Schwierigkeiten, herauszufinden, wie zu entwerfen, wie ein Ding in redux.
Das erste, was mir in den Sinn kam, war ein START_TIMER
Aktion, die würde den ersten offset
Wert. Direkt danach benutze ich setInterval
Feuer aus einem TICK
Aktion immer und immer wieder, dass berechnet, wie viel Zeit vergangen ist, durch Verwendung der offset Hinzugefügt, um die aktuelle Zeit und aktualisiert dann die offset
.
Dieser Ansatz scheint zu funktionieren, aber ich bin mir nicht sicher, wie ich den deaktivieren Sie das Intervall, um es zu stoppen. Auch, wie es scheint, dieses design ist schlecht und es gibt wahrscheinlich einen besseren Weg, es zu tun.
Hier ist eine vollständige JSFiddle hat die START_TIMER
Funktionalität arbeiten. Wenn Sie nur wollen, um zu sehen, was meine reducer aussieht wie jetzt gerade, hier ist es:
const initialState = {
isOn: false,
time: 0
};
const timer = (state = initialState, action) => {
switch (action.type) {
case 'START_TIMER':
return {
...state,
isOn: true,
offset: action.offset
};
case 'STOP_TIMER':
return {
...state,
isOn: false
};
case 'TICK':
return {
...state,
time: state.time + (action.time - state.offset),
offset: action.time
};
default:
return state;
}
}
Ich würde wirklich zu schätzen jede Hilfe.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Würde ich wahrscheinlich empfehlen, geht über das anders: speichern nur den Staat notwendig, um zu berechnen die verstrichene Zeit im Geschäft, und lassen Sie Komponenten, die Ihre eigenen Intervall für jedoch oft Sie wollen, um die Anzeige zu aktualisieren.
Hält diese Aktion löst auf ein minimum — nur Aktionen zu starten und zu stoppen (und reset) die Stoppuhr wird ausgelöst. Denken Sie daran, die Sie zurückgeben, ein neues state-Objekt jedes mal versenden Sie eine Aktion, und jeder
connect
ed Komponente dann neu gerendert, die (obwohl Sie Optimierungen zu vermeiden, zu viele re-rendert innerhalb der gewickelten Komponenten). Außerdem viele, viele Aktion auslöst, kann es schwierig machen, um debug-app-Status-änderungen, da Sie sich mit denTICK
s neben den anderen Aktionen.Hier ein Beispiel:
Ankündigung der action-Macher und-Reduzierer-Angebote nur mit primitiven Werten, und nicht jede Art von Intervall oder eine
TICK
Aktion geben. Nun kann eine Komponente leicht abonnieren, um diese Daten und aktualisieren so oft wie es will: dieMan könnte sogar Anzeige mehrere Timer auf den gleichen Daten mit einem anderen update-Frequenz:
Sehen Sie eine arbeiten JSBin mit dieser Umsetzung hier: https://jsbin.com/dupeji/12/edit?js,Ausgabe
null
stattundefined
? Zweitens, ich bin ein bisschen unsicher über die LinieclearInterval(this.interval);
. Wo warthis.interval
definiert? Oder meintest du zu tunthis.interval = setInterval()
oben? Noch einmal vielen Dank, es bedeutet eine Menge, die Sie würde gehen aus dem Weg, dies zu tun!undefined
so das Standard-argument ingetElapsedTime
funktioniert (durch Undefinierte macht es den Standardwert verwenden, aber das ist nicht der Fall, wenn die übergabe von null). Du hast Recht über die Intervall — werde ich beheben! 🙂stopTimer
mehrmals der timer wird nicht aktualisiert. siehe hierWenn Sie gehen, um diese in eine größere app zu nutzen dann würde ich
requestAnimationFrame
statt einersetInterval
für performance-Probleme. Als Sie zeigt Millisekunden, würden Sie feststellen, dass diese auf mobilen Geräten nicht so viel auf desktop-Browsern.Aktualisiert JSFiddle
https://jsfiddle.net/andykenward/9y1jjsuz
requestAnimationFrame
war für Zeug mitcanvas
wusste ich nicht, ich könnte es in einer situation wie dieser. Von Ihnen positiv bewertet werden!Wollen Sie das
clearInterval
- Funktion, die das Ergebnis eines Aufrufs zusetInterval
(eine eindeutige Kennung) und Stoppt das Intervall, das aus der Ausführung nicht weiter.Also anstatt zu erklären, eine
setInterval
innerhalbstart()
, anstatt übergeben es an die reducer, so dass es speichern kann, dessen ID auf den Staat:Pass
interval
zu dispatcher als Mitglied der action-ObjektStore
interval
auf neuen Staat innerhalb derSTART_TIMER
Aktion reducer______
Die Rendering-Komponente nach
interval
Pass in
interval
als eine Eigenschaft der Komponente:Können wir dann untersuchen Sie den Zustand in out-Komponente für die Darstellung von es nach zu Sie, ob es eine Eigenschaft
interval
oder nicht:______
Stoppen der timer
Um den timer zu stoppen wir löschen das Intervall mit
clearInterval
und einfach anwendeninitialState
wieder:______
Aktualisiert JSFiddle
https://jsfiddle.net/8z16xwd2/2/
setInterval
?Ähnlich andykenward die Antwort, die ich benutzen würde
requestAnimationFrame
um die Leistung zu verbessern, wie die frame-rate der meisten Geräte ist nur zu 60 frames pro Sekunde. Allerdings würde ich so wenig in Redux wie möglich. Wenn Sie nur das Intervall zu lösen Ereignisse aus, die Sie tun können, dass alle auf der Ebene der Komponenten statt in Redux. Siehe Dan Abramov Kommentar in diese Antwort.Unten ist ein Beispiel für ein countdown-Timer Komponente, die die beiden zeigt eine countdown-Uhr und etwas tut, wenn es abgelaufen ist. Innerhalb der
start
,tick
oderstop
können Sie Versand der Ereignisse, die Sie brauchen, um das Feuer in Redux. Ich nur montieren Sie diese Komponente, wenn der timer starten soll.