diff --git a/README.md b/README.md index 8a1a7118c06..2a58e5f1c34 100644 --- a/README.md +++ b/README.md @@ -200,6 +200,27 @@ pending state, where node transforms and DOM reconciliation may not have run yet `editor.getEditorState().read()` will use the latest reconciled `EditorState` (after any node transforms, DOM reconciliation, etc. have already run), any pending `editor.update` mutations will not yet be visible. +**⚠️ Editor Context Gotcha:** `editor.read()` provides editor context (allowing functions like `$getEditor()` to work), +while `editor.getEditorState().read()` does **not** provide editor context by default. If you need editor context +with `editorState.read()`, you must explicitly provide it: + +```js +// ❌ This will throw "Unable to find an active editor" +editor.getEditorState().read(() => { + const editor = $getEditor(); // Error! +}); + +// ✅ This works - editor context provided +editor.getEditorState().read(() => { + const editor = $getEditor(); // Works! +}, { editor }); + +// ✅ This also works - editor.read() provides context automatically +editor.read(() => { + const editor = $getEditor(); // Works! +}); +``` + ::: ### DOM Reconciler diff --git a/packages/lexical-website/docs/concepts/editor-state.md b/packages/lexical-website/docs/concepts/editor-state.md index 8ddd92bf098..d63542c076c 100644 --- a/packages/lexical-website/docs/concepts/editor-state.md +++ b/packages/lexical-website/docs/concepts/editor-state.md @@ -190,6 +190,30 @@ editor.registerUpdateListener(({editorState}) => { }); ``` +:::warning Editor Context Limitation + +Note that `editorState.read()` does not provide editor context by default. Functions like `$getEditor()` +will fail unless you explicitly provide the editor: + +```js +// ❌ This will throw an error +editorState.read(() => { + const editor = $getEditor(); // Error: "Unable to find an active editor" +}); + +// ✅ Provide editor context explicitly +editorState.read(() => { + const editor = $getEditor(); // Works! +}, { editor }); + +// ✅ Or use editor.read() which provides context automatically +editor.read(() => { + const editor = $getEditor(); // Works! +}); +``` + +::: + ## When are Listeners, Transforms, and Commands called? There are several types of callbacks that can be registered with the editor that are related to diff --git a/packages/lexical-website/docs/faq.md b/packages/lexical-website/docs/faq.md index 7131dae22c6..1473d3439b6 100644 --- a/packages/lexical-website/docs/faq.md +++ b/packages/lexical-website/docs/faq.md @@ -156,3 +156,38 @@ also should call `event.preventDefault()` unless your command relies on the browser's native processing of that event. ::: + +## Why does `$getEditor()` throw "Unable to find an active editor" in `editorState.read()`? + +This is a common gotcha! The issue is that `editor.getEditorState().read()` does not provide editor context by default, +while `editor.read()` does. + +**The Problem:** +```js +// ❌ This fails +editor.getEditorState().read(() => { + const editor = $getEditor(); // Throws: "Unable to find an active editor" +}); +``` + +**Solutions:** + +1. **Use `editor.read()` instead** (recommended for most cases): +```js +// ✅ This works +editor.read(() => { + const editor = $getEditor(); // Works! +}); +``` + +2. **Explicitly provide editor context**: +```js +// ✅ This also works +editor.getEditorState().read(() => { + const editor = $getEditor(); // Works! +}, {editor: editor}); +``` + +**When to use which:** +- Use `editor.read()` when you want the latest state including pending updates +- Use `editor.getEditorState().read()` when you want to read from a specific historical state or when called from an update listener diff --git a/packages/lexical-website/docs/intro.md b/packages/lexical-website/docs/intro.md index 5b4d62966c4..47dd2783af6 100644 --- a/packages/lexical-website/docs/intro.md +++ b/packages/lexical-website/docs/intro.md @@ -107,6 +107,31 @@ DOM reconciliation, etc. have already run), any pending `editor.update` mutation ::: +:::warning Editor Context Limitation + +`editor.read()` provides editor context (allowing functions like `$getEditor()` to work), +while `editor.getEditorState().read()` does **not** provide editor context by default. If you need editor context +with `editorState.read()`, you must explicitly provide it: + +```js +// ❌ This will throw "Unable to find an active editor" +editor.getEditorState().read(() => { + const editor = $getEditor(); // Error! +}); + +// ✅ This works - editor context provided +editor.getEditorState().read(() => { + const editor = $getEditor(); // Works! +}, { editor }); + +// ✅ This also works - editor.read() provides context automatically +editor.read(() => { + const editor = $getEditor(); // Works! +}); +``` + +::: + ### DOM Reconciler Lexical has its own DOM reconciler that takes a set of Editor States (always the "current" and the "pending") and applies a "diff"