From c4753fcc3cc16e3db64cd2498604e7c30a5c0683 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Grimm?= Date: Fri, 13 Jan 2023 14:21:03 -0600 Subject: [PATCH] refactor: Remove usage of useEvent with useCallback The `useEvent` function was being called during rendering, which throws an error when React's Strict Mode is enabled. This type of usage is incorrect because it makes the rendering result non-determinisitic. See https://github.com/reactjs/rfcs/pull/220#issuecomment-1118055107 --- src/components/typist-editor.tsx | 82 ++++++++++++++++---------------- 1 file changed, 42 insertions(+), 40 deletions(-) diff --git a/src/components/typist-editor.tsx b/src/components/typist-editor.tsx index fa7af0e3..783d07f1 100644 --- a/src/components/typist-editor.tsx +++ b/src/components/typist-editor.tsx @@ -1,5 +1,4 @@ -import { forwardRef, useImperativeHandle, useMemo } from 'react' -import { useEvent } from 'react-use-event-hook' +import { forwardRef, useCallback, useImperativeHandle, useMemo } from 'react' import { getSchema } from '@tiptap/core' import { Placeholder } from '@tiptap/extension-placeholder' @@ -303,45 +302,48 @@ const TypistEditor = forwardRef(function Typ [ariaDescribedBy, ariaLabel, ariaLabelledBy, editable, schema], ) - const handleCreate = useEvent(function handleCreate(props: CreateProps) { - const { view } = props.editor - - // Apply a selection to the document if one was given and `autoFocus` is `true` - if (autoFocus && contentSelection) { - view.dispatch( - view.state.tr - .setSelection(resolveContentSelection(view.state.doc, contentSelection)) - .scrollIntoView(), - ) - } - - // Move the suggestion plugins to the top of the plugins list so they have a higher priority - // than all input rules (such as the ones used for Markdown shortcuts) - // ref: https://github.com/ueberdosis/tiptap/issues/2570 - if (view.state.plugins.length > 0) { - const restOfPlugins: Plugin[] = [] - const suggestionPlugins: Plugin[] = [] - - view.state.plugins.forEach((plugin) => { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore: The `Plugin` type does not include `key` - if ((plugin.key as string).includes('Suggestion')) { - suggestionPlugins.push(plugin) - } else { - restOfPlugins.push(plugin) - } - }) - - view.updateState( - view.state.reconfigure({ - plugins: [...suggestionPlugins, ...restOfPlugins], - }), - ) - } + const handleCreate = useCallback( + function handleCreate(props: CreateProps) { + const { view } = props.editor + + // Apply a selection to the document if one was given and `autoFocus` is `true` + if (autoFocus && contentSelection) { + view.dispatch( + view.state.tr + .setSelection(resolveContentSelection(view.state.doc, contentSelection)) + .scrollIntoView(), + ) + } + + // Move the suggestion plugins to the top of the plugins list so they have a higher priority + // than all input rules (such as the ones used for Markdown shortcuts) + // ref: https://github.com/ueberdosis/tiptap/issues/2570 + if (view.state.plugins.length > 0) { + const restOfPlugins: Plugin[] = [] + const suggestionPlugins: Plugin[] = [] + + view.state.plugins.forEach((plugin) => { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore: The `Plugin` type does not include `key` + if ((plugin.key as string).includes('Suggestion')) { + suggestionPlugins.push(plugin) + } else { + restOfPlugins.push(plugin) + } + }) + + view.updateState( + view.state.reconfigure({ + plugins: [...suggestionPlugins, ...restOfPlugins], + }), + ) + } - // Invoke the user `onCreate` handle after all internal initializations - onCreate?.(props) - }) + // Invoke the user `onCreate` handle after all internal initializations + onCreate?.(props) + }, + [autoFocus, contentSelection, onCreate], + ) const editor = useEditor( {