Feature: Implement lint rule about using node variable in update closure
Author: levenstaCreated Sep 1, 2026Updated Sep 1, 2026
Labelsenhancement
Description
In some cases, a variable within an update may be closed with a node, especially in the context of React. A contrived example:
const [sourceNode, setSourceNode] = useState<LexicalNode | null>(null)
const [editor] = useLexicalComposerContext();
const handleClick() => {
if (!sourceNode) return;
editor.update(() => {
sourceNode.selectEnd();
});
}The pitfall of this code is that, despite checking for the presence of the sourceNode, it may be missing from the LexicalState for some reason during an update. The correct pattern would be to check via the isAttached() method
- if (!sourceNode) return;
+ if (!sourceNode || !sourceNode.isAttached()) return;or to store the key and check via $getNodeByKey
-const [sourceNode, setSourceNode] = useState<LexicalNode | null>(null)
+const [sourceNodeKey, setSourceNodeKey] = useState<NodeKey>()
const [editor] = useLexicalComposerContext();
const handleClick() => {
+ const sourceNode = $getNodeByKey(sourceNodeKey);
if (!sourceNode) return;
editor.update(() => {
sourceNode.selectEnd();
});
}Otherwise, if the node is detached from the state, the exception will be thrown:
Lexical node does not exist in active editor state.
Avoid using the same node references between nested closures from editorState.read/editor.update.Impact
A lint rule would prevent such potential errors and allow for safer code handling of state. A similar error can occur not only during updating, but also during reading of state
Source: facebook/lexical