Den Editor-State in React verwalten
Das aktuelle Dokument sollte genau einen Besitzer haben. Wählen Sie kontrollierten State, wenn der Rest Ihrer Anwendung jede Änderung braucht; wählen Sie einen unkontrollierten Editor, wenn Sie den Inhalt vor allem beim Speichern lesen müssen. Diese Beispiele verwenden das React-Binding aus npm im HTML-Modus.
Kontrolliert: den lokalen State aktuell halten
"use client";
import { useState } from "react";
import { RichTextEditor } from "@richscripts/richtexteditor/react";
export default function Composer() {
const [html, setHtml] = useState("<p>Start writing...</p>");
return <RichTextEditor
value={html}
onChange={(next) => {
if (typeof next === "string") setHtml(next);
}}
/>;
}Behalten Sie den Wert, den der Editor ausgibt, als Ihren lokalen Bearbeitungswert. Verzögern Sie das Speichern über das Netzwerk separat per Debounce, statt dem Editor absichtlich einen älteren Wert zurückzugeben. Ersetzen Sie nicht nach jedem Speichern das ganze Dokument durch eine vom Server normalisierte Kopie.
Das Binding unterscheidet seine eigenen ausgegebenen Werte von Ersetzungen von außen. Es macht nicht jede Umwandlung durch Ihre Anwendung sicher für die Auswahl. Ein onChange-Handler, der HTML umformatiert und anderen Inhalt zurückgibt, verlangt vom Editor, Inhalt zu ersetzen, während jemand tippt.
Unkontrolliert: das aktuelle HTML beim Speichern lesen
"use client";
import { useRef, useState } from "react";
import { RichTextEditor } from "@richscripts/richtexteditor/react";
import type { RichTextEditorReactHandle } from "@richscripts/richtexteditor/react";
export default function Draft({ initialHtml, onSave }: {
initialHtml: string;
onSave: (html: string) => void;
}) {
const editorRef = useRef<RichTextEditorReactHandle>(null);
const [ready, setReady] = useState(false);
return <>
<RichTextEditor ref={editorRef} defaultValue={initialHtml}
onReady={() => setReady(true)} />
<button type="button" disabled={!ready} onClick={() => {
if (editorRef.current?.getEditor()) {
onSave(editorRef.current.getHTMLCode());
}
}}>Save</button>
</>;
}defaultValue legt den Anfangsinhalt des Dokuments fest; es ist kein Weg, spätere Änderungen in einen gemounteten Editor zu schieben. Die Ref stellt getHTMLCode() bereit. Die Bereitschaftsprüfung verhindert, dass ein vorzeitiges Speichern einen noch nicht initialisierten Editor als leeres Dokument behandelt.
Dieses Beispiel übergibt HTML an den Callback Ihrer Anwendung; es setzt weder Speicherung noch Upload-Abschluss noch die Behandlung von Speicherfehlern um. Sind Bilder aktiviert, verwenden Sie die Abfolge aus Upload und Speichern, bevor Sie das endgültige HTML lesen. Validieren und bereinigen Sie gesendete Inhalte auf dem Server.
Dokumente wechseln und Serverantworten sicher behandeln
- Verwenden Sie eine stabile Identität für das Dokument. Ein
key, der auf dem aktuellen HTML oder einer Zufallszahl basiert, mountet den Editor während der Bearbeitung neu. - Ein bewusst gewählter Schlüssel aus der Dokument-ID kann für ein anderes Dokument einen frischen Editor starten. Lassen Sie einen ungespeicherten Entwurf vor dem Wechsel bestätigen oder speichern; ein erneutes Mounten verwirft den Zustand der Instanz, etwa Auswahl und Rückgängig-Verlauf.
- Wenn Sie Dokumente asynchron laden, ignorieren oder abbrechen Sie eine Antwort für ein Dokument, das nicht mehr ausgewählt ist.
- Führen Sie beim Speichern eine Revision des Dokuments mit. Eine verspätete Antwort sollte den Speicherstatus ihrer eigenen Revision aktualisieren und keinen neueren Entwurf überschreiben. Um ein widersprüchliches Speichern durch einen anderen Benutzer zu erkennen, sind Revisionsprüfungen auf dem Server nötig.
- Wechseln Sie nicht mitten in einer Sitzung zwischen kontrolliertem und unkontrolliertem Modus. Legen Sie das Muster beim Öffnen des Dokuments fest.
Mounten und Strict Mode
Verwenden Sie den mitgelieferten React-Wrapper, statt einen zweiten Editor auf demselben Host zu erstellen. Wenn Sie einen eigenen Wrapper schreiben, erstellen Sie den Editor, nachdem der Host existiert, entfernen Sie beim Cleanup die eigenen Listener und zerstören Sie die eigene Instanz. Ignorieren Sie eine asynchrone Initialisierung, die erst nach dem Unmounten fertig wird.
Der Strict Mode von React kann in der Entwicklung einen zusätzlichen Zyklus aus Setup und Cleanup ausführen. Lassen Sie ihn eingeschaltet, während Sie das Lebenszyklusverhalten prüfen. Für Next.js folgen Sie der Integrationsanleitung für Client Components; das Rendern gespeicherter Inhalte und das Mounten eines interaktiven Editors sind getrennte Aufgaben.
Checkliste zur Fehlerbehebung
- Der Cursor springt: Prüfen Sie wechselnde Keys, neu erstellte Komponenten, wiederholte Aufrufe von
setHTMLCode()und umgewandelte kontrollierte Werte. - Getippter Text verschwindet: Prüfen Sie veraltete Werte aus verzögerten Callbacks, Speicherantworten und Ladevorgängen von Dokumenten.
- Beim Speichern fehlt die letzte Änderung: Lesen Sie die Ref des Editors beim Absenden, statt anzunehmen, dass eine verzögerte Änderungsbenachrichtigung den React-State schon aktualisiert hat.
- Doppelte Symbolleisten: Prüfen Sie doppelte Initialisierung und Cleanup, auch bei Routenwechseln und erneut geöffneten Modals.
- Große Entwürfe wirken langsam: Messen Sie HTML-Serialisierung, Vorschau-Rendering und Speichern über das Netzwerk getrennt voneinander.
- IME-Eingabe funktioniert nicht: Testen Sie die Komposition auf Chinesisch oder Japanisch, ohne den Inhalt währenddessen umzuschreiben, und prüfen Sie Rückgängig, nachdem der Text übernommen wurde.
Weiter: Cursorsprünge Schritt für Schritt diagnostizieren, das React-Binding installieren oder Absenden von Formularen und Speichern und Laden ausprobieren.
Referenzen: React Strict Mode und State erhalten und zurücksetzen.