Set initial state in react-draft-wysiwyg and update state on props change

2.3k views Asked by At

I get rawData as props in html form, so I need to begin with convertFromHTML and then create EditorState which all works fine if I navigate from /article/:articleId -> /article/:articleId/edit but If I go straight to /article/:articleId/edit then it means that articles/:articleId should fetch article first so that it can pass the data to the editor, and when the props change, I need to update the state of the editor.

import React from 'react';
import { EditorState, ContentState, convertFromHTML, convertToRaw } from 'draft-js';
import { Editor } from 'react-draft-wysiwyg';
import draftToHtml from 'draftjs-to-html';
import { Box } from '@mui/material';
import '../node_modules/react-draft-wysiwyg/dist/react-draft-wysiwyg.css';

type TextEditorProps = Readonly<{
  rawData: string;
}>;

export const TextEditor = ({ rawData }: TextEditorProps) => {
  const blocksFromHTML = convertFromHTML(rawData);
  const state = ContentState.createFromBlockArray(
    blocksFromHTML.contentBlocks,
    blocksFromHTML.entityMap,
  );

  const initialState = blocksFromHTML
    ? EditorState.createWithContent(state)
    : EditorState.createEmpty();

  const [editorState, setEditorState] = React.useState<EditorState>(initialState);

  const onEditorStateChange = (editorState: React.SetStateAction<EditorState>) => {
    setEditorState(editorState);
  };

  return (
    <Box component="form" noValidate autoComplete="off">
      <Editor
        editorState={editorState}
        wrapperClassName="demo-wrapper"
        editorClassName="demo-editor"
        onEditorStateChange={onEditorStateChange}
      />
    </Box>
  );
}

This is what I tried:

  useEffect(() => {
    const blocksFromHTML = convertFromHTML(rawData);
    const state = ContentState.createFromBlockArray(
      blocksFromHTML.contentBlocks,
      blocksFromHTML.entityMap,
    );
    if (EditorState.createWithContent(state) !== editorState) {
      setEditorState(EditorState.createWithContent(state));
    }
  }, [state, editorState, rawData]);

But I get this error:

Uncaught Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.

I know why it happens but I cannot see how to fix it.

1

There are 1 answers

0
Abhay verma On
const WYSIWYGEditor = ({ input, meta }) => {
  const blocksFromHTML = convertFromHTML(input.value);
  const content = ContentState.createFromBlockArray(
    blocksFromHTML.contentBlocks,
    blocksFromHTML.entityMap,
  );
  const raw = convertToRaw(content);
  const [contentState, setContentState] = useState(raw);
  const onEditorStateChange = (contentState) => {
    setEditorState(contentState);
    return input.onChange(draftToHtml(convertToRaw(editorState.getCurrentContent())));
  };
  return (
    <div className="editor">
      <Editor
        defaultContentState={contentState}
        onEditorStateChange={onEditorStateChange}
        wrapperClassName="wrapper-class"
        editorClassName="editor-class"
        toolbarClassName="toolbar-class"
        placeholder="Write your answere here"
      />
    </div>
  );
};
export default WYSIWYGEditor;

**This is working fine for me **