Anabel
Anabel

Reputation: 1

BlockNote OnChange Issues in Next JS

After I type in "/" the component re-renders every single time I try to type something, making it unusable.

File A:

  const update = useMutation(api.documents.updateDocument);
  const onChange = (content: string) => {
    update({
      id: params.documentId,
      content,
    });
  };
<Editor onChange={onChange} initialContent={document.content} />

File B:

  const editor: BlockNoteEditor | null = useCreateBlockNote({
    initialContent: initialContent
      ? (JSON.parse(initialContent) as PartialBlock[])
      : undefined,
  });
  const uploadToDatabase = useCallback(() => {
    if (onChange) {
      setTimeout(() => {
        onChange(JSON.stringify(editor.document));
      }, 1000);
    }
  }, [editor, onChange]);
        <BlockNoteView
          onChange={uploadToDatabase}
          editable={editable}
          editor={editor}
          theme={resolvedTheme === "dark" ? "dark" : "light"}
        />

What am I doing wrong? There aren't any errors in the console. Thanks for any help!

I tried using editor.topLevelBlocks which is deprecated now so I used editor.document instead, and now with each symbol I type in the component reloads.

Upvotes: 0

Views: 1155

Answers (3)

Salman-aissam
Salman-aissam

Reputation: 1

I try this and This is works, I use dynamic import for the Editor:

//editor.tsx
"use client";

import { BlockNoteEditor, PartialBlock } from "@blocknote/core";
import { useCreateBlockNote } from "@blocknote/react";
import "@blocknote/shadcn/style.css";
import { BlockNoteView } from "@blocknote/shadcn";
import { useTheme } from "next-themes";
interface EditorProps {
  onChange?: (value: string) => void;
  initialContent?: string;
  editable?: boolean;
}

const Editor = ({ onChange, initialContent, editable }: EditorProps) => {
  const { resolvedTheme } = useTheme();

  const editor: BlockNoteEditor = useCreateBlockNote({
    initialContent: initialContent
      ? (JSON.parse(initialContent) as PartialBlock[])
      : undefined,
  });

  const uploadToDatabase = () => {
    if (onChange) {
        onChange(JSON.stringify(editor.document, null, 2));
    }
  }                 ;

  return (
    <BlockNoteView
      onChange={uploadToDatabase}
      editor={editor}
      editable={editable}
      theme={resolvedTheme === "dark" ? "dark" : "light"}
    />
  );
};

export default Editor;

// page.tsx

"use client"

import {Id} from "@/convex/_generated/dataModel";
import {useMutation, useQuery} from "convex/react";
import {api} from "@/convex/_generated/api";
import {Toolbar} from "@/components/toolbar";
import {Cover} from "@/components/cover";
import {Skeleton} from "@/components/ui/skeleton";
import dynamic from "next/dynamic";
const Editor = dynamic(() =>
    import ("@/components/editor"),
    {ssr:false}
)

interface DocumentIdPageProps {
  params: {
    documentId: Id<"documents">;
  }
}


const DocumentIdPage = ({ params }: DocumentIdPageProps) => {
  const document = useQuery(api.documents.getById, {
    documentId: params.documentId,
  });

  const update = useMutation(api.documents.update);

  const onChange = (content: string) => {
    update({
      id: params.documentId,
      content
    });
  }

  if (document === undefined) {
    return (
      <div>
        <Cover.Skeleton />
        <div className="md:max-w-3xl lg:max-w-4xl mx-auto mt-10">
          <div className="space-y-4 pl-8 pt-4">
            <Skeleton className="h-14 w-[50%]" />
            <Skeleton className="h-4 w-[80%]" />
            <Skeleton className="h-4 w-[40%]" />
            <Skeleton className="h-4 w-[60%]" />
          </div>
        </div>
      </div>
    );
  }

  if (document === null) {
    return <div>Not found</div>;
  }

  return (
    <div className="pb-40">
      <Cover url={document.coverImage} />
      <div className="md:max-w-3xl lg:max-w-4xl mx-auto">
        <Toolbar initialData={document} />
        <Editor onChange={onChange} initialContent={document.content} />
      </div>
    </div>
  );
};

export default DocumentIdPage;

Upvotes: 0

hardiBSalih
hardiBSalih

Reputation: 61

you can use this this code for the Editor Your update is correct

"use client";

import { PartialBlock } from "@blocknote/core";
import { useCreateBlockNote } from "@blocknote/react";
import { BlockNoteView } from "@blocknote/mantine";

import "@blocknote/core/fonts/inter.css";
import "@blocknote/mantine/style.css";
import { useTheme } from "next-themes";
import { useState } from "react";

interface EditorProps {
  onChange: (value: string) => void;
  initialContent?: string;
  editable?: boolean;
}

export default function Editor({
  onChange,
  initialContent,
  editable,
}: EditorProps) {
  const initialBlocks = initialContent ? JSON.parse(initialContent) : undefined;
  const [blocks, setBlocks] = useState<PartialBlock[]>(initialBlocks);
  const editor = useCreateBlockNote({ initialContent: blocks });
  const { resolvedTheme } = useTheme();

  return (
    <BlockNoteView
      editable={editable}
      editor={editor}
      theme={resolvedTheme === "dark" ? "dark" : "light"}
      onChange={() => {
        setBlocks(editor.document);
        onChange(JSON.stringify(blocks));
      }}
    />
  );
}

Upvotes: 0

aashiq durga
aashiq durga

Reputation: 1

Did you use the docs here to ensure ssr is false ?

Upvotes: -1

Related Questions