'How to stop Editor draftJS cursor jumping to beginning of text while typing in React Hooks?

I have the problem with the drafjs plugin which is Editor, thing is it jumps to the beginning of the text when I am typing in the Editor. I have found How to stop DraftJS cursor jumping to beginning of text? this solution, but it is a bit different what I have in my code and in addition I made the component with new feature of React Hooks. Please, could you help me with this issue.

import {
  EditorState, ContentState, convertToRaw,
} from 'draft-js'
import { Editor } from 'react-draft-wysiwyg'
import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css'
import draftToHtml from 'draftjs-to-html'
import htmlToDraft from 'html-to-draftjs'

export default ({ value, onChange }) => {
  const [editorState, setEditorState] = useState(EditorState.createEmpty())

  useEffect(() => {
    setEditorState(
      EditorState.push(
        editorState,
        ContentState.createFromBlockArray(
          htmlToDraft(value || ''),
        ),
      ),
    )
  }, [value])

  return (
    <div className="rich-editor">
      <Editor
        editorState={editorState}
        onEditorStateChange={onEditorStateChange}
        toolbar={{
          options: ['inline'],
          inline: {
            options: ['bold', 'italic', 'underline'],
          },
        }}
      />
    </div>
  )

  function onEditorStateChange(es) {
    setEditorState(es)

    const html = draftToHtml(convertToRaw(es.getCurrentContent()))
    if (value !== html) {
      onChange({ target: { name: 'text', value: html } })
    }
  }
}

For example, enter image description here



Solution 1:[1]

ok I kind of figure out myself. However, it is not the best solution. Basically, I am converting the updated text to Html type, then comparing the value with converted darft.js editorState. Shortly, here is my code, if it helps to anyone in the future

import React, { useEffect, useState } from 'react'
import {
  EditorState, ContentState, convertToRaw,
} from 'draft-js'
import { Editor } from 'react-draft-wysiwyg'
import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css'
import draftToHtml from 'draftjs-to-html'
import htmlToDraft from 'html-to-draftjs'

export default ({ value, onChange }) => {
  const [editorState, setEditorState] = useState(EditorState.createEmpty())

  useEffect(() => {
    if (toHtml(editorState) === value) return //added

    setEditorState(
      EditorState.push(
        editorState,
        ContentState.createFromBlockArray(
          htmlToDraft(value || ''),
        ),
      ),
    )
  }, [value])

  return (
    <div className="rich-editor">
      <Editor
        editorState={editorState}
        onEditorStateChange={onEditorStateChange}
        toolbar={{
          options: ['inline'],
          inline: {
            options: ['bold', 'italic', 'underline'],
          },
        }}
      />
    </div>
  )

  function onEditorStateChange(es) {
    setEditorState(es)
    const html = toHtml(es) //added
    if (value !== html) {
      onChange({ target: { name: 'text', value: html } })
    }
  }

  function toHtml(es) {
    return draftToHtml(convertToRaw(es.getCurrentContent())) // added
  }
}

Solution 2:[2]

Another way is check if the value is empty

useEffect(() => {
  if (value === '') {
      onEditorStateChange(EditorState.createEmpty())
  }

}, [value === ''])

This way, when the value is empty, the editorstatechange is assigned once again as empty.. subsequent times it should work fine as it was initialised to empty and onEditorStateChange will not be called again from useEffect as value is not empty

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Feruza
Solution 2 Shivanand T