Lexical provides several React hooks for accessing editor state and functionality within components.
Context Hooks
useLexicalComposerContext
Access the editor instance and context from within a LexicalComposer.
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
function MyComponent() {
const [editor, context] = useLexicalComposerContext();
// Use editor methods
editor.update(() => {
// Modify editor state
});
// Access theme
const theme = context.getTheme();
return <div>...</div>;
}
Returns: [LexicalEditor, LexicalComposerContextType]
- First element: The
LexicalEditor instance
- Second element: Context object with
getTheme() method
Throws: Error if called outside of a LexicalComposer or LexicalNestedComposer
State Observation Hooks
useLexicalEditable
Subscribe to the editor’s editable state.
import { useLexicalEditable } from '@lexical/react/useLexicalEditable';
function ToolbarButton() {
const isEditable = useLexicalEditable();
return (
<button disabled={!isEditable}>
Format
</button>
);
}
Returns: boolean - Current editable state of the editor
This hook properly handles React StrictMode and concurrency, making it safer than manually using editor.registerEditableListener().
useLexicalIsTextContentEmpty
Check if the editor’s text content is empty.
import { useLexicalIsTextContentEmpty } from '@lexical/react/useLexicalIsTextContentEmpty';
function CharacterCount() {
const [editor] = useLexicalComposerContext();
const isEmpty = useLexicalIsTextContentEmpty(editor, true);
return <div>{isEmpty ? 'Empty' : 'Has content'}</div>;
}
Parameters:
The editor instance to observe.
If true, whitespace-only content is considered empty.
Returns: boolean - Whether the editor’s text content is empty
useLexicalSubscription
Generic hook for subscribing to Lexical editor values for render.
import { useLexicalSubscription } from '@lexical/react/useLexicalSubscription';
import type { LexicalSubscription } from '@lexical/react/useLexicalSubscription';
function useMyCustomState(): MyState {
const subscription = useCallback((editor: LexicalEditor): LexicalSubscription<MyState> => {
return {
initialValueFn: () => editor.getEditorState().read(() => {
// Return initial value
return computeState();
}),
subscribe: (callback) => {
return editor.registerUpdateListener(() => {
const newValue = editor.getEditorState().read(() => {
return computeState();
});
callback(newValue);
});
},
};
}, []);
return useLexicalSubscription(subscription);
}
Parameters:
subscription
(editor: LexicalEditor) => LexicalSubscription<T>
required
Function that creates a subscription object. Must have a stable identity (use useCallback or define at module scope).
Returns: T - The current value from the subscription
The subscription object must provide:
initialValueFn: () => T - Function to compute the initial value
subscribe: (callback: (value: T) => void) => () => void - Function to register updates and return cleanup
Selection and Node Hooks
useLexicalNodeSelection
Manage selection state for a specific node (useful for decorators and custom nodes).
import { useLexicalNodeSelection } from '@lexical/react/useLexicalNodeSelection';
function ImageComponent({ nodeKey }) {
const [isSelected, setSelected, clearSelection] = useLexicalNodeSelection(nodeKey);
return (
<div
className={isSelected ? 'selected' : ''}
onClick={() => setSelected(true)}
>
<img src="..." />
</div>
);
}
Parameters:
The node key to track selection for.
Returns: [boolean, (selected: boolean) => void, () => void]
isSelected (boolean): Whether the node is currently selected
setSelected (function): Set the selection state of the node
- Parameters:
selected: boolean - true to select, false to deselect
clearSelection (function): Clear the node selection
useLexicalTextEntity
Register text entity transformations (e.g., mentions, hashtags, custom tokens).
import { useLexicalTextEntity } from '@lexical/react/useLexicalTextEntity';
import { MentionNode } from './nodes/MentionNode';
function MentionPlugin() {
const createMentionNode = useCallback((textNode) => {
return new MentionNode(textNode.getTextContent());
}, []);
const getMentionMatch = useCallback((text) => {
const match = /@[\w]+/.exec(text);
if (match) {
return {
end: match.index + match[0].length,
start: match.index,
};
}
return null;
}, []);
useLexicalTextEntity(
getMentionMatch,
MentionNode,
createMentionNode
);
return null;
}
Parameters:
getMatch
(text: string) => EntityMatch | null
required
Function to find entity matches in text. Returns an object with start and end indices, or null.
targetNode
Klass<T extends TextNode>
required
The node class to create for matched entities.
createNode
(textNode: TextNode) => T
required
Factory function to create the entity node from a text node.
Returns: void
Type Definitions
LexicalSubscription
type LexicalSubscription<T> = {
initialValueFn: () => T;
subscribe: (callback: (value: T) => void) => () => void;
};
Object describing how to subscribe to a value in the editor.
Function that returns the initial value. Called during render.
subscribe
(callback: (value: T) => void) => () => void
required
Function that registers a callback for updates. Returns a cleanup function.
EntityMatch
type EntityMatch = {
start: number;
end: number;
};
Describes the position of a text entity match.
Starting index of the match in the text.
Ending index of the match in the text.