fix: handle flushSync error when remounting useEditor in React 19#7549
fix: handle flushSync error when remounting useEditor in React 19#7549bxff wants to merge 3 commits intoueberdosis:mainfrom
Conversation
🦋 Changeset detectedLatest commit: 7c1037b The changes in this PR will be included in the next version bump. This PR includes changesets to release 72 packages
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 |
✅ Deploy Preview for tiptap-embed ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
9f9716b to
5eda073
Compare
Wraps the flushSync call in ReactRenderer's constructor with a try-catch. When flushSync throws (because React is already in a render/commit phase), it falls back to queueMicrotask — the same path already used for non-initialized editors. Closes ueberdosis#7543
5eda073 to
0f34655
Compare
bdbch
left a comment
There was a problem hiding this comment.
Thanks for the PR and for digging into the React 19 remount case. I'm going to reject this as-is because the new try/catch is a bit too broad: it doesn't just catch the flushSync lifecycle error, it will also swallow real errors thrown by this.render() and then retry them in a microtask. That changes the current failure mode, makes debugging harder, and could hide unrelated regressions.
I think this needs to be narrowed so we only fall back for the specific flushSync-during-render/commit failure, while rethrowing everything else. A focused test for that fallback path would also help a lot.
Closes #7543
What this PR does
Wraps the
flushSynccall inReactRenderer's constructor with a try-catch. WhenflushSyncthrows (because React is already in a render/commit phase), it falls back toqueueMicrotask— the same path already used for non-initialized editors.flushSyncsucceeds → synchronous ProseMirror/React rendering (no behavior change)flushSyncthrows → graceful fallback to async renderWhy
React 19 may remount keyed components when a list is reordered, even with stable keys. When this happens during
useEditor's effect cycle,ReactRenderergets constructed during React's commit phase, andflushSyncthrows a hard error.Reproduction
Reporter's React 19 sandbox: https://codesandbox.io/p/sandbox/tiptap-flushsync-reorder-19-x47nq7
React 18 comparison (works fine): https://codesandbox.io/p/sandbox/tiptap-flushsync-reorder-18-w7ttcg