Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Runtime Error: this._editorJS.destroy is not a function #190

Open
minhhieu1612 opened this issue Apr 7, 2022 · 16 comments
Open

Runtime Error: this._editorJS.destroy is not a function #190

minhhieu1612 opened this issue Apr 7, 2022 · 16 comments
Labels
bug Something isn't working

Comments

@minhhieu1612
Copy link

minhhieu1612 commented Apr 7, 2022

Environment

  • @editorjs/editorjs version: 2.23.2
  • react-editor-js version: 2.0.6

Describe

I currently using next.js version 12.1.4.
And the error occurs after the ClientEditorCore instance initial success as you can see below:
image

Also, there are two editors components mount on the page:
image

Editor.tsx file:

import React, { useEffect, useRef, useState } from "react";
import { EditorBlockPropsType } from "./index.type";
import { createReactEditorJS } from "react-editor-js";
import { ClientEditorCore } from "@react-editor-js/client/dist/client/src/client-editor-core";

const ReactEditorJS = createReactEditorJS();
const REACT_EDITOR_HOLDER_ID = "ssrHolder";

const EditorBlock = ({ content }: EditorBlockPropsType) => {
  let editorInstance;
  const [tools, setTools] = useState<any>();
  const initialValue = content || {
    time: 1635603431943,
    blocks: [
      {
        id: "sheNwCUP5A",
        type: "header",
        data: {
          text: "Editor.js",
          level: 2,
        },
      },
    ],
  };

  useEffect(() => {
    (async () => {
      const importedTools = await import("./editorTools");
      setTools(importedTools.EDITOR_JS_TOOLS);
    })();
    // console.log(EditorJS);
  }, []);

  if (!tools) {
    return <>Loading....</>;
  }

  return (
    <ReactEditorJS
      holder={REACT_EDITOR_HOLDER_ID}
      instanceRef={(instance: any) => (editorInstance = instance)}
      tools={tools}
      defaultValue={initialValue}
      placeholder="write something here..."
      onInitialize={(currentEditor: ClientEditorCore) =>
        console.log(currentEditor)
      }
    />
  );
};

export default EditorBlock;

editorTools.ts file:

import Embed from "@editorjs/embed";
import Table from "@editorjs/table";
import List from "@editorjs/list";
import Warning from "@editorjs/warning";
import Code from "@editorjs/code";
import LinkTool from "@editorjs/link";
import Image from "@editorjs/image";
import Raw from "@editorjs/raw";
import Header from "@editorjs/header";
import Quote from "@editorjs/quote";
import Marker from "@editorjs/marker";
import CheckList from "@editorjs/checklist";
import Delimiter from "@editorjs/delimiter";
import InlineCode from "@editorjs/inline-code";
import SimpleImage from "@editorjs/simple-image";

export const EDITOR_JS_TOOLS = {
  embed: Embed,
  table: Table,
  marker: Marker,
  list: List,
  warning: Warning,
  code: Code,
  linkTool: LinkTool,
  image: Image,
  raw: Raw,
  header: Header,
  quote: Quote,
  checklist: CheckList,
  delimiter: Delimiter,
  inlineCode: InlineCode,
  simpleImage: SimpleImage,
};

My github repo
Thank for support me,

@minhhieu1612 minhhieu1612 added the bug Something isn't working label Apr 7, 2022
@proteye
Copy link

proteye commented Apr 7, 2022

I have the same error. Please fix it.

@stale
Copy link

stale bot commented Apr 16, 2022

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the inactive label Apr 16, 2022
@Jungwoo-An
Copy link
Owner

I'm sorry for the late response. I'll fix it.

If you want to contribute this repo, feel free to create pull request.

@mrspence
Copy link

mrspence commented Apr 20, 2022

Suspect this is caused when the react component is created and destroyed before Editor JS is fully loaded (Editor JS has a pending promise on editorJS.isReady that resolves once fully loaded).

This means if you call _editorJS.destroy() before the underlying Editor JS is fully loaded, an error is thrown... codex-team/editor.js#919 (comment)

Temporary fix is don't create / destroy your react editor js component within ~3 seconds, suspect actual fix for react-editor-js is await _editorJS.isReady and then _editorJS.destroy()

@AlbinoGeek
Copy link

AlbinoGeek commented Apr 21, 2022

Yeah... this results in the package failing in NextJS.

Specifically, even with SSR disabled, two EditorJS components render, and this error is thrown.

@AdrianSchneider
Copy link

We just went through this as well: two components and a destroy error.

In our case, it was only broken in React 18. Downgrading to 17 fixed it for us.

@AlbinoGeek
Copy link

AlbinoGeek commented Apr 21, 2022

We just went through this as well: two components and a destroy error.

In our case, it was only broken in React 18. Downgrading to 17 fixed it for us.

Incredible! This at least lets me try and develop with this.

Temporary Workaround

# Downgrade to React 17 (and matching react-* packages)
# works for NextJS as well;
npx yarn add react@^17 react-dom@^17
# or
yarn add react@^17 react-dom@^17
# or
npm install react@^17 react-dom@^17

Result in package.json

{
  "dependencies": {
    "react": "^17",
    "react-dom": "^17",
  }
}

@StitiFatah
Copy link

StitiFatah commented May 14, 2022

Are you guys sure it's a react version problem ? Just got this error with .focus after updating react-editor-js to 2.0.6 and downgrading to [email protected] solved it

@AlbinoGeek
Copy link

AlbinoGeek commented May 14, 2022 via email

@skworden
Copy link

skworden commented May 25, 2022

I'm using React 18 and Next 12, and this plugin was duplicating the editor, and throwing destroy is not a function error.

I fixed it by removing this plugin and using the default editorjs.

import EditorJS from "@editorjs/editorjs";
import { useEffect, useId, useRef } from "react";

const Editor = () => {
  const holder = useId();
  const editor = useRef<EditorJS | null>(null);

  useEffect(() => {
    if (!editor.current) {
      editor.current = new EditorJS({
        data: { blocks: [] },
        holder,
        tools: {},
      });
    }
    return () => {
      if (editor.current && editor.current.destroy) {
        editor.current.destroy();
      }
    };
  }, []);

  return <div id={holder} ref={editor}></div>;
};
export default Editor;

If you use Next.js, you can import the component to work with SSR.

const Editor = dynamic(() => import("path/to/editor"), { ssr: false });

@bekogeko
Copy link

in next.js its giving an error about usage of useRef
image
second error is same

@bekogeko
Copy link

i realised its about strict mode and double invoking when its double invoked (its also means enviroment is in strict mode) its creates double instance and because of that one of them creates this error. Becase one of them is still null !!!

@tinwritescode
Copy link

tinwritescode commented Oct 5, 2022

Work for me:

const [tools, setTools] = useState<any>()

useEffect(() => {
  ;(async () => {
    const importedTools = await import('../components/editor-config')
    setTools(importedTools.EDITOR_JS_TOOLS)
  })()
}, [])
<EditorJs
  onInitialize={(editor: any) => {
    editorRef.current = editor
  }}
  placeholder="Notes"
  minHeight={100}
  onChange={(value: any) => {
    setFieldValue('note', value)
  }}
  tools={tools}
/>

@Avinash1721
Copy link

This issue is coming because with react 18 page is rendered twice. To avoid this, turn off the strict mode in next.config.js

https://nextjs.org/docs/api-reference/next.config.js/react-strict-mode
https://reactjs.org/docs/strict-mode.html#ensuring-reusable-state

@berkaygurbuz
Copy link

I'm using React 18 and Next 12, and this plugin was duplicating the editor, and throwing destroy is not a function error.

I fixed it by removing this plugin and using the default editorjs.

import EditorJS from "@editorjs/editorjs";
import { useEffect, useId, useRef } from "react";

const Editor = () => {
  const holder = useId();
  const editor = useRef<EditorJS | null>(null);

  useEffect(() => {
    if (!editor.current) {
      editor.current = new EditorJS({
        data: { blocks: [] },
        holder,
        tools: {},
      });
    }
    return () => {
      if (editor.current && editor.current.destroy) {
        editor.current.destroy();
      }
    };
  }, []);

  return <div id={holder} ref={editor}></div>;
};
export default Editor;

If you use Next.js, you can import the component to work with SSR.

const Editor = dynamic(() => import("path/to/editor"), { ssr: false });

When I use your workaround, I couldn't write anything in input

@AlbinoGeek
Copy link

AlbinoGeek commented Nov 13, 2022 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests