5

I am trying to use the Editor of EditorJS. Everything works fine, except that when I first load the page it initializes two editors at the beginning and keeps appending new editors everytime I reload the page. But they are all inside the <div id='editorjs' /> div. Is there something I am missing?

// react etc. imports
import EditorJS from '@editorjs/editorjs'

const EditorComponent = (props) => {
    const [input, setInput] = useState({})
    const currentuser = useSelector((state) => state.currentuser)

    const editor = new EditorJS({
        holderId: 'editorjs',
        autofocus: true,
    })

    const postNews = () => {
        // POSTING SUTFF
    }

    return (
        <Grid>
            <Grid templateRows='auto min-content' gap={6}>
                <div id='editorjs' />
                <Button onClick={postNews}>Post news</Button>
            </Grid>
        </Grid>
    )
}

Two editors

Here is a screenshot from the dom where two editors are added immediately after loading the page.

PRSHL
  • 1,359
  • 1
  • 11
  • 30
  • 3
    Move the `new EditorJs` statement outside of the function body. It's creating a new one every render. – Brian Thompson Jun 15 '21 at 16:58
  • But when I do move it outside it can't find the id of the holding div. – PRSHL Jun 15 '21 at 17:08
  • 1
    Because the `div` does not exist in the DOM yet. I guess you could try putting it in a `useEffect` with an empty dependency array? – Brian Thompson Jun 15 '21 at 17:09
  • Yeah I tried it with useEffect and the empty dependency array, but it keeps on adding new editors. But I think thats just a problem during development with the hot reload, and should not appear in production. Thank you – PRSHL Jun 15 '21 at 17:13
  • I know it's too late, but you could use useRef to store editorJs instance so if check ref's current value if it's null then creates new instance only if ref is null...don't forget to assign new instance to ref.current – Bakaji Apr 05 '22 at 15:00

4 Answers4

2

I removed the react strict mode and it helped me

ForeverBetter
  • 21
  • 1
  • 2
  • 1
    This solved it for me. I disabled strict mode in both tsconfig and next.config and it started working for me. Till now it was rendering two instances of EditorJS and rendering empty containers. – Deepak Thomas Dec 27 '22 at 17:56
  • Also found the reason why some legacy components are rendering twice on nextjs https://stackoverflow.com/questions/61254372/my-react-component-is-rendering-twice-because-of-strict-mode/61897567#61897567 – Deepak Thomas Dec 27 '22 at 18:21
1

The key is to use editor.isReady which is provided by editorjs. If it is true then EditorJS is already running.

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

const Editor = () => {
  let editor = { isReady: false };
  useEffect(() => {
    if (!editor.isReady) {
      editor = new EditorJS({
        holder: "editorjs",
      });
    }
  }, []);
  return (
    <main>
      <div id="editorjs"></div>
    </main>
  );
};

export default Editor;
Sharath kumar
  • 1,118
  • 13
  • 17
0

Found a simple solution

const <Your Component Name> = () => {
const [editor, setEditor] = useState("");

useEffect(() => {
  setEditor(() => new EditorJS(PostEditorConfig()));
  }, []);


// .... other components
return (
<div id=editorjs></div>
)}
bumba
  • 29
  • 1
0

This worked for me. In useEffect(), I first checked to make sure if the editor is in its default state, (""), then proceed to create a new instance of EditorJS, otherwise skip it.

const [editor, setEditor] = useState("")

useEffect(() => {
    editor === "" && setEditor( () => new EditorJS({
      holder: "editorjs",
      logLevel: "VERBOSE",
      placeholder: "Any new inspirations today?",
    }))   
    
}, [])
Pawel Veselov
  • 3,996
  • 7
  • 44
  • 62
David
  • 31
  • 3