Multiple draft-js-plugins editors on the same page don't work

I'm trying to use multiple rich text editors in a React form. I built the editor component using draft-js and also I integrated the inline toolbar from draft-js-plugins. Because this is a react-hook-form I wrapped the editor inside a Controller component.

The problem I have is that the InlineToolbar is displayed only for the last editor component in page.

Based on the draft-js-plugins documentation the initialization of the toolbar should happen outside the component so this is what I did:

const inlineToolbarPlugin = createInlineToolbarPlugin();
const { InlineToolbar } = inlineToolbarPlugin;
const plugins = [inlineToolbarPlugin];

function RichTextEditor({ control, name }) {
  return (
    <div>
      <Controller
        name={name}
        control={control}
        render={({ field: { value, onChange } }) => {
          const newValue = value || EditorState.createEmpty();
          return (
            <>
              <Editor
                editorState={newValue}
                onChange={onChange}
                plugins={plugins}
              />
              <InlineToolbar />
            </>
          );
        }}
      />
    </div>
  );
}

A complete CodeSandbox example here: CodeSandbox link


Each editor get's its own plugins.

You can solve this issue ether by creating different plugin for each editor instance and pass them to the editor OR with create a function for creating a plugin inside the editor component and every time we init a editor we create a new plugin instance

So, this is the first solution:

  const inlineToolbarPlugin1 = createInlineToolbarPlugin();
  const { InlineToolbar:Tool1 } = inlineToolbarPlugin1;

  const inlineToolbarPlugin2 = createInlineToolbarPlugin();
  const { InlineToolbar:Tool2 } = inlineToolbarPlugin2;

And pass them into your custom editor components.


Second solution:

  import React from "react";
import { Controller } from "react-hook-form";
import { EditorState } from "draft-js";
import PropTypes from "prop-types";
import Editor from "@draft-js-plugins/editor";
import createInlineToolbarPlugin from "@draft-js-plugins/inline-toolbar";
import "@draft-js-plugins/inline-toolbar/lib/plugin.css";
import "draft-js/dist/Draft.css";

const createtoolbarplugin = () => {
  const InlineToolbarPlugin = createInlineToolbarPlugin();
  const InlineToolbar = InlineToolbarPlugin.InlineToolbar;
  return {
    InlineToolbarPlugin,
    InlineToolbar
  };
};

function AnotherRichTextEditor({ control, aName }) {
  const [{ InlineToolbarPlugin, InlineToolbar }] = React.useState(() => {
    const { InlineToolbar, InlineToolbarPlugin } = createtoolbarplugin();
    return {
      InlineToolbarPlugin,
      InlineToolbar
    };
  });

  return (
    <div
      style={{
        border: "1px solid #ccc",
        minHeight: 30,
        padding: 10
      }}
    >
      <Controller
        name={aName}
        control={control}
        render={({ field: { value, onChange } }) => {
          const newValue = value || EditorState.createEmpty();
          return (
            <>
              <Editor
                editorState={newValue}
                onChange={onChange}
                plugins={[InlineToolbarPlugin]}
              />
              <InlineToolbar />
            </>
          );
        }}
      />
    </div>
  );
}

AnotherRichTextEditor.propTypes = {
  control: PropTypes.object,
  aName: PropTypes.string
};

export default AnotherRichTextEditor;

Hope That's help