Skip to content

Comments

Fix Slate component to properly handle editor updates by adding `edit…#6012

Merged
dylans merged 2 commits intoianstormtaylor:mainfrom
changlin-cn:fix-6011
Feb 20, 2026
Merged

Fix Slate component to properly handle editor updates by adding `edit…#6012
dylans merged 2 commits intoianstormtaylor:mainfrom
changlin-cn:fix-6011

Conversation

@changlin-cn
Copy link
Contributor

Description
In packages/slate-react/src/components/slate.tsx, the useIsomorphicLayoutEffect that subscribes to document focusin/focusout (or focus/blur) uses a callback that reads editor, but the effect has an empty dependency array []. That causes a stale closure: the listener fn always refers to the editor from the first render. If the parent ever passes a different editor instance (e.g. after remount or when editor is recreated), the effect does not re-run, so the document-level listeners keep calling ReactEditor.isFocused(editor) with the old editor. That can lead to wrong isFocused state in context and, in edge cases, to using an unmounted or replaced editor.

Issue
Fixes: Bug: Stale editor in focus listener effect in Slate component

…or` as a dependency in the useEffect hook.
@changeset-bot
Copy link

changeset-bot bot commented Feb 10, 2026

🦋 Changeset detected

Latest commit: 89a18de

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
slate-react Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link
Collaborator

@dylans dylans left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may be on purpose, but I'm not remembering. Maybe @12joan remembers?

Also this will need a changeset to get released if it is needed.

@12joan
Copy link
Contributor

12joan commented Feb 11, 2026

It looks like an accidental omission to me, especially since the useEffect above has no purpose other than to support the editor being replaced.

  const [isFocused, setIsFocused] = useState(ReactEditor.isFocused(editor))

  useEffect(() => {
    setIsFocused(ReactEditor.isFocused(editor))
  }, [editor])

@jsauca
Copy link

jsauca commented Feb 13, 2026

Here is quick fix for me:

  // Force Slate remount when the editor instance changes
  // slate-react's focusin/focusout listener has [] deps, capturing the initial
  // editor forever — remounting resets the closure with the correct editor.
  const slateKeyRef = useRef(0);
  const prevEditorRef = useRef(editor);
  if (editor !== prevEditorRef.current) {
    prevEditorRef.current = editor;
    slateKeyRef.current += 1;
  }

<Slate
    key={slateKeyRef.current}
  />

@changlin-cn
Copy link
Contributor Author

This may be on purpose, but I'm not remembering. Maybe @12joan remembers?

Also this will need a changeset to get released if it is needed.

If this is intentional, it will cause the useFocused hook to return an incorrect value after the editor instance is recreated. Additionally, the changeset has been updated.

@dylans dylans merged commit 57bdd4f into ianstormtaylor:main Feb 20, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Stale editor in focus listener effect in Slate component

4 participants