4

I have been trying to get draft js mention plugin to work with react hooks but can't seem to figure what's wrong with the code. Appreciate any help on this.

import React, { useRef, useState, useEffect } from "react";
import { EditorState } from "draft-js";
import Editor from "draft-js-plugins-editor";
import createMentionPlugin, { defaultSuggestionsFilter } from "draft-js-mention-plugin";
import mentions from "./mentions";

export default function MentionEditor() {
  const [editorState, setEditorState] = useState(EditorState.createEmpty());
  const [suggestions, setSuggestions] = useState(mentions);
  const editor = useRef(null);

  useEffect(() => {
    editor.current.focus();
  }, [])

  const mentionPlugin = createMentionPlugin();
  const { MentionSuggestions } = mentionPlugin;
  const plugins = [mentionPlugin];

  const onSearchChange = ({ value }) => {
    setSuggestions(defaultSuggestionsFilter(value, mentions))
  };

  return (
    <div style={{ border: "1px solid gray" }}>
      <Editor
        editorState={editorState}
        onChange={editorState => setEditorState(editorState)}
        plugins={plugins}
        ref={editor}
      />
      <MentionSuggestions
        onSearchChange={onSearchChange}
        suggestions={suggestions}
      />
    </div> 
  );
}
Adrian
  • 105
  • 2
  • 6

3 Answers3

8

You need to move the draft-js plugin configuration outside the component arrow function. This is a pretty basic Draft-JS implementation using a functional component and hooks:

import React, { useState, useRef } from 'react'
import { EditorState } from 'draft-js'
import Editor from 'draft-js-plugins-editor'
import createMentionPlugin, { defaultSuggestionsFilter } from 'draft-js-mention-plugin'
import 'draft-js/dist/Draft.css'
import 'draft-js-mention-plugin/lib/plugin.css'
import mentions from "./mentions"

// Draft-JS-Mentions plugin configuration
const mentionPlugin = createMentionPlugin()
const { MentionSuggestions } = mentionPlugin
const plugins = [mentionPlugin]

const MyEditor= () => {
    const [suggestions, setSuggestions] = useState(mentions)

    // Draft-JS editor configuration
    const [editorState, setEditorState] = useState(
        () => EditorState.createEmpty(),
    )
    const editor = useRef(null)

    // Check editor text for mentions
    const onSearchChange = ({ value }) => {
        setSuggestions(defaultSuggestionsFilter(value, mentions))
    }

    const onAddMention = () => {

    }

    // Focus on editor window
    const focusEditor = () => {
        editor.current.focus()
    }

    return (
            <div onClick={() => focusEditor()}>
                <Editor
                    ref={editor}
                    editorState={editorState}
                    plugins={plugins}
                    onChange={editorState => setEditorState(editorState)}
                    placeholder={'Type here...'}
                />
                <MentionSuggestions
                    onSearchChange={onSearchChange}
                    suggestions={suggestions}
                    onAddMention={onAddMention}
                />
            </div>
    )
}

export default MyEditor
FX2000
  • 141
  • 6
1

Just move these lines outside component and it will work:

  const mentionPlugin = createMentionPlugin();
  const { MentionSuggestions } = mentionPlugin;
  const plugins = [mentionPlugin];

export default function MentionEditor() {
        const [editorState, setEditorState] = useState(EditorState.createEmpty());
.. ... ... 
}
Rohit Khanna
  • 693
  • 5
  • 15
0

!!!!!!!!!!!!!!!! PAY ATTENTION !!!!!!!!!!!!

The onSearchChange method will be triggered once the '@' character is typed, so in this case it will return just 5 items that fit the empty string...

To prevent this to be happened, just check that the value we want to search is not empty:

const onSearchChange = ({ value }) => {
    if (value) {
      setSuggestions(defaultSuggestionsFilter(value, mentions));
    }
  };
Ahmad MOUSSA
  • 2,729
  • 19
  • 31