Adrian
Adrian

Reputation: 105

Using Draft js mention plugin with react hooks

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> 
  );
}

Upvotes: 4

Views: 5816

Answers (3)

Ahmad MOUSSA
Ahmad MOUSSA

Reputation: 2906

!!!!!!!!!!!!!!!! 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));
    }
  };

Upvotes: 0

FX2000
FX2000

Reputation: 141

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

Upvotes: 8

Rohit Khanna
Rohit Khanna

Reputation: 723

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());
.. ... ... 
}

Upvotes: 1

Related Questions