Datenbindung & Zustandsverwaltung im React Scheduler
Der React Scheduler unterstützt zwei Muster der Datenbindung:
- React-Zustand als Quelle der Wahrheit (empfohlen für die meisten React-Apps)
- Scheduler als Quelle der Wahrheit (nützlich für spezialisierte, Hochdurchsatz-Fälle)
Beide Modelle sind gültig. Wählen Sie pro Bildschirm ein Modell und halten Sie es konsistent.
Wenn Sie noch kein einfaches Diagramm gerendert haben, beginnen Sie mit dem Schneller Einstieg.
Datenmodelle
React-Zustand als Quelle der Wahrheit (empfohlen)
In diesem Modell:
- speichern Sie
events(und oftview/date) im React-Zustand oder in einem Zustand-Manager - übergeben Sie diesen Zustand als Props an
<ReactScheduler /> - Scheduler ruft
data.save/data.batchSaveauf, wenn Benutzer Daten bearbeiten - Sie aktualisieren den Zustand, und React rendert den Scheduler erneut mit den neuen Props
Verwenden Sie dies, wenn andere React-Komponenten mit Scheduler-Daten synchronisiert bleiben müssen.
Scheduler als Quelle der Wahrheit
In diesem Modell:
- Scheduler lädt und ändert Daten intern
- Sie geben Bearbeitungen optional an Backend-Endpunkte weiter
- React spiegelt nicht jedes Ereignis-Update im Zustand wider
Verwenden Sie dieses Modell, wenn React nicht jedes einzelne Scheduler-Update sofort widerspiegeln muss.
React-Zustand als Quelle der Wahrheit
Minimalbeispiel
import { useMemo, useState } from "react";
import ReactScheduler, { type Event } from "@dhtmlx/trial-react-scheduler";
import "@dhtmlx/trial-react-scheduler/dist/react-scheduler.css";
import { seedEvents } from "./seed/data";
export default function ReactStateScheduler() {
const [events, setEvents] = useState<Event[]>(seedEvents);
const data = useMemo(
() => ({
save: (entity: string, action: string, item: Event, id: string | number) => {
if (entity !== "event") return;
if (action === "create") {
setEvents((prev) => [...prev, item]);
return;
}
if (action === "update") {
setEvents((prev) => prev.map((e) => (e.id === id ? item : e)));
return;
}
if (action === "delete") {
setEvents((prev) => prev.filter((e) => e.id !== id));
}
},
}),
[]
);
return (
<div style={{ height: "100vh" }}>
<ReactScheduler events={events} data={data} />
</div>
);
}
Dieses Muster macht React zum zentralen Eigentümer der Ereignisdaten.
Behandlung von Aktualisierungen mit data.save
data.save wird bei jeder Benutzeränderung aufgerufen:
(entity: string, action: string, item: any, id: string | number) => void | Promise<any>
Für Scheduler-Ereignis-CRUD:
entityist"event"actionist"create" | "update" | "delete"itemist das erstellte/aktualisierte/gelöschte Ereignisidist die betroffene Ereignis-ID
Backend-orientiertes Beispiel
const data = {
save: async (entity: string, action: string, item: any, id: string | number) => {
if (entity !== "event") return;
if (action === "create") {
const response = await fetch("/api/events", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(item),
});
const created = await response.json();
return { id: created.id };
}
if (action === "update") {
await fetch(`/api/events/${id}`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(item),
});
return;
}
if (action === "delete") {
await fetch(`/api/events/${id}`, { method: "DELETE" });
}
},
};
Wenn Ihr Backend temporäre IDs bei der Erstellung ersetzt, geben Sie { id: realId } zurück, damit Scheduler Client- und Server-IDs abgleichen kann.
Massenaktualisierungen mit data.batchSave
data.batchSave ist sinnvoll, wenn viele Änderungen in kurzer Zeit auftreten (zum Beispiel bei dichten Bearbeitungssitzungen).
Verwenden Sie es, wenn Sie möchten:
- Anfragenanzahl reduzieren, indem gruppierte Änderungen gesendet werden
- Aktualisierungen in einer einzigen Reduzer-/Store-Transaktion verarbeiten
<ReactScheduler
events={events}
data={{
batchSave: async (changes) => {
await fetch("/api/events/batch", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(changes),
});
},
}}
/>
Verwenden Sie save für einfache Änderungslogik pro Änderung und batchSave für gruppierte Synchronisierung.
Laden von Daten in den React-Zustand
Im vom React getriebenen Modell bezieht Scheduler Daten aus dem React-Zustand. Häufige Quellen:
- lokaler Komponenten-Zustand
- globaler Zustand-Manager (Redux Toolkit, Zustand, MobX, XState, Jotai, Valtio)
- API-Aufrufe
Lokaler Zustandsquelle
import { useState } from "react";
import ReactScheduler, { type Event } from "@dhtmlx/trial-react-scheduler";
import { seedEvents, seedView, seedDate } from "./seed/data";
export default function LocalStateExample() {
const [events] = useState<Event[]>(seedEvents);
return (
<ReactScheduler
events={events}
view={seedView}
date={seedDate}
/>
);
}
Zustand-Manager-Quelle
Jede Bibliothek folgt dem gleichen Ablauf:
- Selektor/Hook liest den Zustand
- Props füttern den Scheduler
data.savelöst Aktionen/Store-Mutationen aus
const events = useSchedulerStore((s) => s.events);
const onSave = useSchedulerStore((s) => s.handleSave);
<ReactScheduler events={events} data={{ save: onSave }} />;
Zustand-Manager-Tutorials:
- Verwendung des React Scheduler mit Redux Toolkit
- Verwendung des React Scheduler mit Zustand
- Verwendung des React Scheduler mit MobX
- Verwendung des React Scheduler mit XState
- Verwendung des React Scheduler mit Jotai
- Verwendung des React Scheduler mit Valtio
API-Ladequelle
import { useEffect, useState } from "react";
import ReactScheduler, { type Event } from "@dhtmlx/trial-react-scheduler";
export default function SchedulerWithApi() {
const [events, setEvents] = useState<Event[] | null>(null);
useEffect(() => {
let disposed = false;
(async () => {
const response = await fetch("/api/events");
const payload = await response.json();
if (!disposed) setEvents(payload.events || []);
})();
return () => {
disposed = true;
};
}, []);
if (!events) return <div>Loading Scheduler...</div>;
return <ReactScheduler events={events} />;
}
Scheduler als Quelle der Wahrheit
In diesem Modus rendert React die Komponente, hält jedoch keinen kanonischen Ereigniszustand.
URL-Transportbeispiel
<ReactScheduler
data={{
load: "/api/scheduler/load",
save: "/api/scheduler/save",
}}
/>
Callback-Transportbeispiel
<ReactScheduler
data={{
load: async () => {
const response = await fetch("/api/scheduler/load");
return response.json();
},
save: async (entity, action, item, id) => {
await fetch("/api/scheduler/save", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ entity, action, item, id }),
});
},
}}
/>
Verwenden Sie diesen Ansatz, wenn Scheduler den primären Laufzeitspeicher bleiben kann und React nicht jedes einzelne Update rendern muss.
Das richtige Modell auswählen
Verwenden Sie das von React getriebene Modell, wenn:
- mehrere React-Komponenten von Scheduler-Daten abhängen
- Sie eine vorhersehbare globale Zustandsintegration benötigen
- Sie eine klare Undo/Redo-Funktion im App-Zustand wünschen
Verwenden Sie das vom Scheduler getriebene Modell, wenn:
- React größtenteils als Shell/Layout fungiert
- Sie bevorzugen Scheduler-gesteuerte Laufzeitmutationen
- der Server-Transport der primäre Synchronisationsmechanismus ist