CodeMirror mount-timing in React
Definitie
CodeMirror 6 initialiseert zijn interne document op het moment dat de React-component mount. Als de initiële content op dat moment nog niet beschikbaar is (async load), wordt de editor aangemaakt met een leeg document en blijft leeg — ook als de prop later een waarde krijgt.
Context
Dit probleem doet zich voor wanneer content asynchroon geladen wordt (bijvoorbeeld via fetch, callTool, of IndexedDB) en de initialContent-prop pas na de mount-aanroep zijn waarde krijgt. Omdat CodeMirror zijn state intern beheert en niet via React re-renders, heeft een prop-update na mount geen effect.
Kernpunten
Symptoom: Editor is leeg ondanks dat initialContent correct ingesteld wordt.
Oorzaak: useEffect([], []) (mount-only) maakt de EditorView aan met de waarde van doc op dat moment. Latere wijzigingen in de prop worden genegeerd.
Oplossing — loaded-flag:
Render de component pas nadat content beschikbaar is:
const [loaded, setLoaded] = useState(false);
const [initialContent, setInitialContent] = useState('');
useEffect(() => {
async function load() {
const text = await fetchContent();
setInitialContent(text);
setLoaded(true);
}
load();
}, [assetId]);
// In JSX:
{loaded && <MarkdownEditor initialContent={initialContent} />}Alternatief — setContent imperatively:
Gebruik een ref met een setContent-methode die dispatch aanroept:
setContent: (text: string) => {
view.dispatch({ changes: { from: 0, to: view.state.doc.length, insert: text } });
}Dit vereist extra logica om te voorkomen dat de gebruiker ondertussen al getypt heeft.
Aanbeveling: De loaded-flag is eenvoudiger en voorkomt een flash van lege editor. De imperatieve aanpak is beter als content ook tijdens een sessie opnieuw geladen moet worden.
Bijwerking van de loaded-flag: Extensies die afhankelijk zijn van de content (zoals isTranscript-detectie) moeten óók na de load bepaald worden, niet bij het openen van het asset. Zo voorkom je mismatch tussen extensions en weergegeven tekst.
Verbanden
- Zie ook: autosave-en-advisory-lock-patronen
- Gerelateerd project: Atelier (vault-app)
Bronnen
CodeMirror 6 documentatie: https://codemirror.net/docs/guide/