15

None of the demos that I've seen for Draft-js (by Facebook, built on React) show how to clear the input field after submit. For example, see this code pen linked to from awesome-draft-js where the value you submit remains in the input field after submit. There's also no function in the api that seems designed to do it. What I've done to achieve that is to create a new empty state on button submission like this

onSubmit(){
this.setState({
   editorState: EditorState.createEmpty(),
})
}

However, since I create an empty state in the constructor when the editor is loaded like this

  this.state = {
    editorState: EditorState.createEmpty(),
  };

I'm worried that I might not be doing it in the right way i.e. the previous state object might become a memory leak. Question: what is the intended way to reset the state in the above situation (i.e. button submit)

Leahcim
  • 40,649
  • 59
  • 195
  • 334
  • 3
    I created an example of what you are after and it seems to work okay. I've filled the draft-js editor with some default content on mount. Clicking the submit button empties the state using the `EditorState.createEmpty()` function. Seems fine. http://www.webpackbin.com/NkNbdZlXZ – ctrlplusb May 26 '16 at 15:47

4 Answers4

34

It is NOT recommended to use EditorState.createEmpty() to clear the state of the editor -- you should only use createEmpty on initialization.

The proper way to reset content of the editor:

import { EditorState, ContentState } from 'draft-js';

const editorState = EditorState.push(this.state.editorState, ContentState.createFromText(''));
this.setState({ editorState });

@source: https://github.com/draft-js-plugins/draft-js-plugins/blob/master/FAQ.md

Sahil
  • 489
  • 5
  • 8
  • 4
    You may want to pass the third parameter too. `EditorState.push(editorState, ContentState.createFromText(''), 'remove-range')` – Searene Feb 21 '18 at 00:38
  • any explanations why it's not recommended to use `EditorState.createEmpty()`? It works good for me. – Stalinko Feb 05 '19 at 12:22
  • 1
    @Stalinko it might induce `getEditorState is not a function` error someday. – goodhyun Jun 17 '19 at 13:52
  • This answer is not correct. This answer indeed messes with the cursor on the next input. @Fabian's answer should be selected as the correct answer – Sihoon Kim Jul 06 '21 at 03:52
  • cursor bug will happen with this solution, but to fix that add this line `editorRef.current.focus()` after update the state. – Raad Altaie Nov 14 '22 at 21:25
7

@Vikram Mevasiya's solution does not clear block list styles correctly

@Sahil's solution messes with the cursor on the next input

I found that this is the only working solution:

// https://github.com/jpuri/draftjs-utils/blob/master/js/block.js
const removeSelectedBlocksStyle = (editorState)  => {
    const newContentState = RichUtils.tryToRemoveBlockStyle(editorState);
    if (newContentState) {
        return EditorState.push(editorState, newContentState, 'change-block-type');
    }
    return editorState;
}

// https://github.com/jpuri/draftjs-utils/blob/master/js/block.js
export const getResetEditorState = (editorState) => {
    const blocks = editorState
        .getCurrentContent()
        .getBlockMap()
        .toList();
    const updatedSelection = editorState.getSelection().merge({
        anchorKey: blocks.first().get('key'),
        anchorOffset: 0,
        focusKey: blocks.last().get('key'),
        focusOffset: blocks.last().getLength(),
    });
    const newContentState = Modifier.removeRange(
        editorState.getCurrentContent(),
        updatedSelection,
        'forward'
    );

    const newState = EditorState.push(editorState, newContentState, 'remove-range');
    return removeSelectedBlocksStyle(newState)
}

Its a combination of two helper functions provided by https://github.com/jpuri/draftjs-utils . Didn't want to npm install the entire package for this. It resets the cursor state but keeps the block list styling. This is removed by applying removeSelectedBlocksStyle() I just can't belive how a library this mature doesn't offer a one-line reset feature.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Fabian
  • 748
  • 2
  • 11
  • 20
3

Try this

    let editorState = this.state.editorState
    let contentState = editorState.getCurrentContent()
    const firstBlock = contentState.getFirstBlock()
    const lastBlock = contentState.getLastBlock()
    const allSelected = new SelectionState({
        anchorKey: firstBlock.getKey(),
        anchorOffset: 1,
        focusKey: lastBlock.getKey(),
        focusOffset: lastBlock.getLength(),
        hasFocus: true
    })
    contentState = Modifier.removeRange(contentState, allSelected, 'backward')
    editorState = EditorState.push(editorState, contentState, 'remove-range')
    editorState = EditorState.forceSelection(contentState, contentState.getSelectionAfter())
    this.setState({editorState})
1
const content = {
  entityMap: {},
  blocks:[
    { 
      key: "637gr",
      text: "",
      type:"unstyled",
      depth:0,
      inlineStyleRanges:[],
      entityRanges: [],
      data: {}
    }
  ]
};
  1. const [editorContent, setEditorContent] = useState(content);

  2. <Editor contentState={editorContent} />

contentState prop does the trick after saving you can use setEditorContent to reset the editor

setEditorContent(content)
MichaelM
  • 964
  • 7
  • 20