From b59374482e2d884202d1ae1819ab37cca60e5bd6 Mon Sep 17 00:00:00 2001 From: Marco Wettstein Date: Thu, 2 Feb 2023 17:16:33 +0100 Subject: [PATCH] fix(slate): slate loses some updates / keystrokes (#1275) this does not solve it entirly, but mitigatates the problem a lot the issue stems from the fact that slate became an uncontrolled input which makes it hard to use with outside values --- .../slate/src/components/SlateProvider.tsx | 41 ++++++++----------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/packages/plugins/content/slate/src/components/SlateProvider.tsx b/packages/plugins/content/slate/src/components/SlateProvider.tsx index 73bef169a..761d7f367 100644 --- a/packages/plugins/content/slate/src/components/SlateProvider.tsx +++ b/packages/plugins/content/slate/src/components/SlateProvider.tsx @@ -1,5 +1,6 @@ import { deepEquals } from '@react-page/editor'; import type { FC, PropsWithChildren } from 'react'; + import React, { useCallback, useEffect, useMemo } from 'react'; import { createEditor, Transforms } from 'slate'; import { ReactEditor, Slate, withReact } from 'slate-react'; @@ -18,9 +19,11 @@ const SlateProvider: FC> = (props) => { )(withReact(withInline(plugins)(createEditor()))), [] ); - - useEffect(() => { - // unfortunatly, slate broke the controlled input pattern. So we have to hack our way around it, see https://github.com/ianstormtaylor/slate/issues/4992 + // We abuse useMemo for a side effect + // don't try this at home! + // unfortunatly, slate broke the controlled input pattern. So we have to hack our way around it, see https://github.com/ianstormtaylor/slate/issues/4992 + // doing it in a `useEffect` works, but there are still timing issues where updates are lost and inconsistency arise + useMemo(() => { editor.children = data?.slate; try { // focus @@ -37,27 +40,19 @@ const SlateProvider: FC> = (props) => { } }, [data?.slate, data?.selection]); - const onChange = useCallback( - (v: any) => { - if ( - !deepEquals(editor.children, data?.slate) || - !deepEquals(editor.selection, data?.selection) - ) { - props.onChange( - { - slate: editor.children, - selection: editor.selection, - }, - { - // mark as not undoable when state is same - // that happens if only selection was changed - notUndoable: deepEquals(editor.children, data?.slate), - } - ); + const onChange = useCallback(() => { + props.onChange( + { + slate: editor.children, + selection: editor.selection, + }, + { + // mark as not undoable when state is same + // that happens if only selection was changed + notUndoable: deepEquals(editor.children, data?.slate), } - }, - [data?.slate, props.onChange] - ); + ); + }, [data?.slate, props.onChange]); const initialValue = data?.slate;