Ich schreibe gerade eine React-Anwendung, wo ich auf den nächsten Kalendereintrag in meinem Redux-Zustand hören muss.Dispatch-Aktion für ein bestimmtes Datum-Zeit
Ich suche Beratung, wie dies am effektivsten zu tun und zu korrigieren.
Mein calendar
Zustand Minderer besteht aus:
entries: [
{
title: "Event 1",
start: "2016-09-26T08:00:00.000Z"
end: "2016-09-26T09:00:00.000Z"
},
{
title: "Event 2",
start: "2016-09-26T10:00:00.000Z"
end: "2016-09-26T11:00:00.000Z"
},
{
title: "Event 3",
start: "2016-09-26T13:00:00.000Z"
end: "2016-09-26T14:00:00.000Z"
}
]
Wenn das nächste Ereignis (Ereignis 1) passieren wird, würde Ich mag ein Ereignis versenden, den Zustand dieses Kalendereintrag zu handhaben. Die Einträge Reducer können jederzeit aktualisiert werden, so dass ich in der Lage sein muss, Einträge früher als der nächste Eintrag zu schieben.
Ich habe Redux und Redux Saga zur Verfügung für den Umgang damit.
Zeit mit einem Redux Saga Zuhörer wie ich arbeite:
export default function * watchCalendar() {
while (true) {
const entry = yield select((state) => state.calendar.entries[0]);
if (entry) {
const now = moment().startOf("minute");
const start = moment(entry.start);
if (now.isAfter(start)) {
put(CalendarActions.setActiveEntry(entry));
}
}
}
}
Aber nicht wie erwartet funktioniert, wie die while
wird nach dem ersten Versuch zu beenden. Ich muss es weiter auf den Staat hören lassen. Das oben genannte ist nicht wirklich so effektiv, wie ich es gerne hätte.
Alle Ratschläge, Ideen oder Codebeispiele sind willkommen.
UPDATE 1, 2, 3, 4
ich ein bisschen bin immer noch Hacking, ein Stück näher:
export function * watchNextCalendarEntry() {
while (true) { // eslint-disable-line no-constant-condition
const next = yield select((state) => CalendarSelectors.getNextEntry(state.calendar));
if (next) {
const start = moment(next.start);
const seconds = yield call(timeleft, start);
yield call(delay, seconds * 1000);
yield put(CalendarActions.setActiveCalendarEntry(next));
}
}
}
function * currentCalendarEntry(action) {
try {
while (true) { // eslint-disable-line no-constant-condition
const entry = action.payload;
const end = moment(entry.end);
const seconds = yield call(timeleft, end);
yield call(delay, seconds * 1000);
yield put(CalendarActions.setInactiveCalendarEntry(entry));
}
}
finally {
if (yield cancelled()) {
// e.g. do something
}
}
}
export function * watchCurrentCalendarEntry() {
while (true) { // eslint-disable-line no-constant-condition
const action = yield take(ActionTypes.SET_ACTIVE_CALENDAR_ENTRY);
const watcher = yield fork(currentCalendarEntry, action);
yield take(ActionTypes.SET_INACTIVE_CALENDAR_ENTRY);
yield cancel(watcher);
}
}
function getTimeLeft(date) {
return date.diff(moment().startOf("second"), "seconds");
}
Gute Idee beim Abonnieren des nächsten Eintrags - wenn also ein anderer Eintrag kommt, zählen wir dazu. Stellen Sie nur sicher, dass der "nächste" Eintrag auch der nächste Eintrag in der Zeit ist. – janhartmann
Ja, also nextEntry muss der nächste Eintrag sein. Wenn das Sinn macht, können Sie dies in der Sage berechnen, müssen aber den 'Select'-Effekt verwenden – yjcxy12