From 53395449e5b03fde5c0521203ef044064f3c159e Mon Sep 17 00:00:00 2001 From: Joe Anderson Date: Wed, 21 Jun 2023 19:09:32 +0100 Subject: [PATCH] Do not try to batch updates in React >= 18 (#5460) * Do not try to batch updates in React >= 18 * Linter fixes * Add changeset --- .changeset/nice-shirts-flash.md | 5 +++++ packages/slate-react/src/components/slate.tsx | 4 ++-- packages/slate-react/src/plugin/with-react.ts | 15 +++++++++++---- packages/slate-react/src/utils/environment.ts | 3 +-- 4 files changed, 19 insertions(+), 8 deletions(-) create mode 100644 .changeset/nice-shirts-flash.md diff --git a/.changeset/nice-shirts-flash.md b/.changeset/nice-shirts-flash.md new file mode 100644 index 000000000..e8b43aba2 --- /dev/null +++ b/.changeset/nice-shirts-flash.md @@ -0,0 +1,5 @@ +--- +'slate-react': patch +--- + +Do not attempt to batch updates manually in React >= 18 diff --git a/packages/slate-react/src/components/slate.tsx b/packages/slate-react/src/components/slate.tsx index 301e32bab..83204940f 100644 --- a/packages/slate-react/src/components/slate.tsx +++ b/packages/slate-react/src/components/slate.tsx @@ -9,7 +9,7 @@ import { } from '../hooks/use-slate-selector' import { EditorContext } from '../hooks/use-slate-static' import { ReactEditor } from '../plugin/react-editor' -import { IS_REACT_VERSION_17_OR_ABOVE } from '../utils/environment' +import { REACT_MAJOR_VERSION } from '../utils/environment' import { EDITOR_TO_ON_CHANGE } from '../utils/weak-maps' /** @@ -78,7 +78,7 @@ export const Slate = (props: { useIsomorphicLayoutEffect(() => { const fn = () => setIsFocused(ReactEditor.isFocused(editor)) - if (IS_REACT_VERSION_17_OR_ABOVE) { + if (REACT_MAJOR_VERSION >= 17) { // In React >= 17 onFocus and onBlur listen to the focusin and focusout events during the bubbling phase. // Therefore in order for 's handlers to run first, which is necessary for ReactEditor.isFocused(editor) // to return the correct value, we have to listen to the focusin and focusout events without useCapture here. diff --git a/packages/slate-react/src/plugin/with-react.ts b/packages/slate-react/src/plugin/with-react.ts index c6e6a2f1a..15a8d7065 100644 --- a/packages/slate-react/src/plugin/with-react.ts +++ b/packages/slate-react/src/plugin/with-react.ts @@ -36,6 +36,7 @@ import { NODE_TO_KEY, } from '../utils/weak-maps' import { ReactEditor } from './react-editor' +import { REACT_MAJOR_VERSION } from '../utils/environment' /** * `withReact` adds React and DOM specific behaviors to the editor. @@ -324,11 +325,17 @@ export const withReact = ( } e.onChange = options => { - // COMPAT: React doesn't batch `setState` hook calls, which means that the - // children and selection can get out of sync for one render pass. So we - // have to use this unstable API to ensure it batches them. (2019/12/03) + // COMPAT: React < 18 doesn't batch `setState` hook calls, which means + // that the children and selection can get out of sync for one render + // pass. So we have to use this unstable API to ensure it batches them. + // (2019/12/03) // https://github.com/facebook/react/issues/14259#issuecomment-439702367 - ReactDOM.unstable_batchedUpdates(() => { + const maybeBatchUpdates = + REACT_MAJOR_VERSION < 18 + ? ReactDOM.unstable_batchedUpdates + : (callback: () => void) => callback() + + maybeBatchUpdates(() => { const onContextChange = EDITOR_TO_ON_CHANGE.get(e) if (onContextChange) { diff --git a/packages/slate-react/src/utils/environment.ts b/packages/slate-react/src/utils/environment.ts index 327326a7d..c66b4421e 100644 --- a/packages/slate-react/src/utils/environment.ts +++ b/packages/slate-react/src/utils/environment.ts @@ -1,7 +1,6 @@ import React from 'react' -export const IS_REACT_VERSION_17_OR_ABOVE = - parseInt(React.version.split('.')[0], 10) >= 17 +export const REACT_MAJOR_VERSION = parseInt(React.version.split('.')[0], 10) export const IS_IOS = typeof navigator !== 'undefined' &&