TypeCellOS / BlockNote

A React Rich Text Editor that's block-based (Notion style) and extensible. Built on top of Prosemirror and Tiptap.
https://www.blocknotejs.org/
Mozilla Public License 2.0
5.9k stars 384 forks source link

`i.view is undefined` with `editor.replaceBlocks` or `editor.removeBlocks` #810

Open ikazaksoftaria opened 4 weeks ago

ikazaksoftaria commented 4 weeks ago

Hello! I want to update content in BlockNoteView component. And when I try to replace blocks with Editor API I get this error:

TypeError: i.view is undefined log screenshot

Code

export const Content = ({ contentJson }: { contentJson: string }) => {
  const editor = useCreateBlockNote({ initialContent: JSON.parse(contentJson) });

  useEffect(() => {
    try {
      editor.replaceBlocks(editor.document, JSON.parse(contentJson));
    } catch (e) {
      editor.removeBlocks(editor.document);
    }
  }, [editor, contentJson]);

  return <BlockNoteView editor={editor} editable={false} />;
};

What is the current working alternative to dynamically update content in BlockNoteView component?

Versions @blocknote/shadcn: "0.13.5" Node: v18.19.1 System: Manjaro Linux

ikazaksoftaria commented 4 weeks ago

My solution


export const Content = ({ contentJson }: { contentJson: string }) => {
  const [editor, setEditor] = useState<BlockNoteEditor>(BlockNoteEditor.create({ initialContent: JSON.parse(contentJson) }));

  useEffect(() => {
    setEditor(BlockNoteEditor.create({ initialContent: JSON.parse(contentJson) }));
  }, [news.content]);

  return <BlockNoteView editor={editor} editable={false} />
};
YousefED commented 4 weeks ago

This is probably an edge case where immediately calling replaceBlocks before the editor has fully initialized throws an error. We'll look into this

ikazaksoftaria commented 4 weeks ago

This is probably an edge case where immediately calling replaceBlocks before the editor has fully initialized throws an error. We'll look into this

Yes! It does work with await new Promise((resolve) => setTimeout(resolve, 10));

export const Content = ({ contentJson }: { contentJson: string }) => {
  const editor = useCreateBlockNote({ initialContent: JSON.parse(contentJson) });

  useEffect(() => {
    new Promise((resolve) => setTimeout(resolve, 10)).then(() => {
      try {
        editor.replaceBlocks(editor.document, JSON.parse(contentJson));
      } catch (e) {
        editor.removeBlocks(editor.document);
      }
    });
  }, [editor, contentJson]);

  return <BlockNoteView editor={editor} editable={false} />;
};