Skip to content

Commit

Permalink
fix: tiptap might cause runtime react/DOM errors when remounting the …
Browse files Browse the repository at this point in the history
…editor (#477)

* fix: tiptap might cause runtime react/DOM errors when remounting the editor

See: ueberdosis/tiptap#3764 (comment)

* update tiptap deps
  • Loading branch information
baiirun authored Aug 28, 2023
1 parent aac6705 commit 71400a8
Show file tree
Hide file tree
Showing 3 changed files with 279 additions and 486 deletions.
20 changes: 10 additions & 10 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,21 @@
"@tanstack/react-query": "^4.28.0",
"@tanstack/react-query-devtools": "^4.29.19",
"@tanstack/react-table": "^8.5.13",
"@tiptap/core": "2.0.3",
"@tiptap/extension-bubble-menu": "2.0.3",
"@tiptap/core": "2.1.7",
"@tiptap/extension-bubble-menu": "2.1.7",
"@tiptap/extension-bullet-list": "^2.0.3",
"@tiptap/extension-gapcursor": "^2.0.3",
"@tiptap/extension-gapcursor": "^2.1.7",
"@tiptap/extension-hard-break": "^2.0.3",
"@tiptap/extension-heading": "^2.0.3",
"@tiptap/extension-image": "2.0.3",
"@tiptap/extension-image": "2.1.7",
"@tiptap/extension-list-item": "^2.0.3",
"@tiptap/extension-paragraph": "^2.0.3",
"@tiptap/extension-placeholder": "2.0.3",
"@tiptap/html": "2.0.3",
"@tiptap/pm": "2.0.3",
"@tiptap/react": "2.0.3",
"@tiptap/starter-kit": "2.0.3",
"@tiptap/suggestion": "2.0.0-beta.220",
"@tiptap/extension-placeholder": "2.1.7",
"@tiptap/html": "2.1.7",
"@tiptap/pm": "2.1.7",
"@tiptap/react": "2.1.7",
"@tiptap/starter-kit": "2.1.7",
"@tiptap/suggestion": "2.1.7",
"@vercel/analytics": "^0.1.6",
"@vercel/og": "^0.5.4",
"boring-avatars": "^1.7.0",
Expand Down
46 changes: 26 additions & 20 deletions apps/web/partials/editor/editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import HardBreak from '@tiptap/extension-hard-break';
import Image from '@tiptap/extension-image';
import ListItem from '@tiptap/extension-list-item';
import Placeholder from '@tiptap/extension-placeholder';
import { EditorContent, FloatingMenu, useEditor } from '@tiptap/react';
import { Content, EditorContent, FloatingMenu, useEditor } from '@tiptap/react';
import StarterKit from '@tiptap/starter-kit';

import * as React from 'react';
Expand Down Expand Up @@ -77,33 +77,39 @@ export const Editor = React.memo(function Editor({
}: Props) {
const { editorJson, spaceId, updateEditorBlocks, blockIds } = useEntityPageStore();

const editor = useEditor({
extensions: [...tiptapExtensions, createIdExtension(spaceId)],
editable: true,
content: editorJson,
onBlur({ editor }) {
// Responsible for converting all editor blocks to triples
// Fires after the IdExtension's onBlur event which sets the "id" attribute on all nodes
updateEditorBlocks(editor);
},
editorProps: {
transformPastedHTML: html => removeIdAttributes(html),
},
});

// @HACK: Janky but works for now.
//
// We only want to render the editor once the editorJson has been hydrated with local data.
// We shouldn't re-render the editor every time the editorJson changes as that would result
// in a janky UX. We let the editor handle block state internally while each block handles
// it's own state.
const hasHydrated = useHydrated();

const editor = useEditor(
{
extensions: [...tiptapExtensions, createIdExtension(spaceId)],
editable: true,
content: hasHydrated ? editorJson : undefined,
onBlur({ editor }) {
// Responsible for converting all editor blocks to triples
// Fires after the IdExtension's onBlur event which sets the "id" attribute on all nodes
updateEditorBlocks(editor);
},
editorProps: {
transformPastedHTML: html => removeIdAttributes(html),
},
},
[hasHydrated]
);
React.useEffect(() => {
// The timeout is needed to workaround a react error in tiptap
// https://github.com/ueberdosis/tiptap/issues/3764#issuecomment-1546629928
setTimeout(() => {
editor?.commands.setContent(editorJson);
});
// commands is not memoized correctly by tiptap, so we need to disable the rule, else the
// effect will run infinitely.
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [editorJson]);

// We are in edit mode and there is no content.
if (!editable && blockIds.length === 0) return <>{placeholder}</>;
if (!editable && blockIds.length === 0) return <span>{placeholder}</span>;

if (!editor) return null;

Expand Down
Loading

1 comment on commit 71400a8

@vercel
Copy link

@vercel vercel bot commented on 71400a8 Aug 28, 2023

Choose a reason for hiding this comment

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

Please sign in to comment.