editor.js
editor.js copied to clipboard
Editor.destroy()
I want to destroy the editor instance manually and then set it again when the component is updated. I am using ReactJs but I am not using the react wrapper. Whenever I try to call the destroy function I got the error that destroy is not a function.
const MyEditor = () => {
const [editor, setEditor] = useState([]);
useEffect(() => {
if (editor.length != 0) {
editor.destroy();
}
setEditor(
new EditorJS({
holder: "editor",
placeholder: "Insert your text here!",
tools: {
header: Header,
list: List,
quote: Quote,
checklist: Checklist,
code: Code,
table: Table,
image: {
class: ImageTool,
config: {
endpoints: {
byFile: "myFile",
byUrl: "myUrl"
}
}
}
},
data: {
blocks: myBlocks
}
})
);
}, [myData]);
Make sure you call destroy() on the editor instance. Try to debug editor variable, looks like it stores something different.
Although I got this when I try to debug the editor variable.
t {isReady: Promise}
clear: ƒ ()
configuration: {holder: "editor", placeholder: "Insert your event details here!", tools: {…}, data: {…}, initialBlock: "paragraph", …}
destroy: ƒ ()
emit: ƒ (e, n)
focus: ƒ ()
isReady: Promise {
Maybe editor is already destroyed?
No. When I run the code it gives me 2 instances of the editor on the page. So, I want the first instance to be destroyed
Ok we will test it.
if (editor.length != 0) {
editor.destroy();
}
Looks like editor is an Array. Try editor[0].destroy()
any update on this issue? I have the same problem, every time I try to destroy the editor instance, it keeps saying that the destroy is not a function.
you can use it inside isReady
editor.isReady .then(() => { // editor.destroy(); /** Do anything you need after editor initialization */ });
For anyone getting this error, editor can not be destroyed while it is loading!
any updates on this matter?
I have a TypeError when running destroy() on the editor instance.
Unhandled Runtime Error
TypeError: Cannot read property 'deactivate' of null
getting this now with read only mode
I am facing the same issue but i will come up with some solution try this
`"use client"; import React, { useEffect, useState, MutableRefObject } from 'react'; import EditorJS from '@editorjs/editorjs';
interface UpdateEditorProps{ editorRef: MutableRefObject<EditorJS | null> initialData: any }
const Editor = ({ editorRef , initialData}:UpdateEditorProps) => { const [isMounted, setIsMounted] = useState(false);
const initializeEditor = async () => {
// @ts-ignore
const EditorJS = (await import('@editorjs/editorjs')).default;
// @ts-ignore
const Header = (await import('@editorjs/header')).default;
// @ts-ignore
const List = (await import('@editorjs/list')).default;
// @ts-ignore
const Embed = (await import('@editorjs/embed')).default;
// @ts-ignore
const Table = (await import('@editorjs/table')).default;
// @ts-ignore
const Quote = (await import('@editorjs/quote')).default;
// @ts-ignore
const Marker = (await import('@editorjs/marker')).default;
// @ts-ignore
const Warning = (await import('@editorjs/warning')).default;
// @ts-ignore
const LinkTool = (await import('@editorjs/link')).default;
// @ts-ignore
const RawTool = (await import('@editorjs/raw')).default;
// @ts-ignore
const Delimiter = (await import('@editorjs/delimiter')).default;
// @ts-ignore
const InlineCode = (await import('@editorjs/inline-code')).default;
// @ts-ignore
const SimpleImage = (await import('@editorjs/simple-image')).default;
// @ts-ignore
const Checklist = (await import('@editorjs/checklist')).default;
// @ts-ignore
const WarningTool = (await import('@editorjs/warning')).default;
// @ts-ignore
const CodeBox = (await import('@bomdi/codebox')).default;
if (!editorRef.current) {
const editor = new EditorJS({
holder: 'editorjs',
onReady: () => {
editorRef.current = editor;
},
placeholder: 'Type here to write your content...',
inlineToolbar: true,
data: initialData,
tools: {
header: {
class: Header,
config: {
placeholder: 'Enter a header',
levels: [1,2, 3, 4,5,6],
defaultLevel: 1
}
},
list: List,
embed: Embed,
table: Table,
quote: Quote,
marker: Marker,
warning: Warning,
code: {
class: CodeBox,
config: {
themeURL: 'https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/styles/dracula.min.css',
themeName: 'atom-one-dark',
},
},
linkTool: {
class: LinkTool,
config: {
endpoint: '/api/blog/link',
},
},
raw: RawTool,
delimiter: Delimiter,
inlineCode: InlineCode,
simpleImage: SimpleImage,
checklist: Checklist,
},
});
editorRef.current = editor;
}
};
useEffect(() => {
if (typeof window !== 'undefined') {
setIsMounted(true);
}
}, []);
useEffect(() => {
const init = async () => {
await initializeEditor();
};
if (isMounted) {
init();
return () => {
editorRef.current?.destroy();
editorRef.current = null;
};
}
}, [isMounted]);
return (
<div className='mt-4'>
<div id="editorjs" className="prose max-w-full border rounded-sm py-10 px-10" />
</div>
);
}
export default Editor; `
I ran into this issue. The reason it's rendering twice is because React runs lifecycle functions like useEffect twice when in Strict Mode (which is enabled by default in development environments)
This component only renders the editor once and only destroys it if it has the destroy function (which it will only have if it is fully initialized)
import { Box } from "@chakra-ui/react";
import { useEffect, useRef } from "react";
import EditorJS from "@editorjs/editorjs";
import colors from "tailwindcss/colors";
export default function MarkdownEditor() {
const editorRef = useRef<HTMLDivElement>(null)
const editorInstance = useRef<EditorJS | null>(null);
useEffect(() => {
if (!editorRef.current || editorInstance.current) {
return
}
editorInstance.current = new EditorJS({
holder: editorRef.current,
})
return () => {
if (editorInstance.current?.destroy) {
editorInstance.current.destroy()
}
}
}, [editorRef.current]);
return (
<Box>
<Box ref={ editorRef }></Box>
</Box>
)
}