NewScientists
NewScientists

Reputation: 1262

Simple undo and redo button with Draftjs

i am trying to get a simple undo and redo button working to start off with. So far i have tried reading through the documentation on the draftjs website but it feels quite cryptic and there are no examples of what i am trying to do.

Here is what i have attempted so far, on click of the undo it does nothing. Not sure what i am missing. Thanks in advance.

import React from 'react';
import ReactDOM from 'react-dom';
import {Editor, EditorState} from 'draft-js';

class MyEditor extends React.Component {
  constructor(props) {
    super(props);
    this.state = {editorState: EditorState.createEmpty()};
    this.onChange = (editorState) => this.setState({editorState});
  }

  onClick() {
    this.setState({
      editorState: EditorState.undo(editorState)
    })
  }

  render() {
    return (
      <div>
      <button onClick={this.onClick.bind(this)}>undo</button>
        <Editor editorState={this.state.editorState} onChange={this.onChange} />
        </div>
    );
  }
}

ReactDOM.render(
  <MyEditor />,
  document.getElementById('root')
);

Upvotes: 1

Views: 4129

Answers (3)

Rami Salim
Rami Salim

Reputation: 192

You can easily use the Undo/Redo plugin provided by the draft team

check it out please

Upvotes: 0

NewScientists
NewScientists

Reputation: 1262

This is the fix, i needed to reference the editorstate correctly like so, then i refactored based on Simon's answer:

import React from 'react';
import ReactDOM from 'react-dom';
import {Editor, EditorState} from 'draft-js';

class MyEditor extends React.Component {
  constructor(props) {
    super(props);
    this.state = {editorState: EditorState.createEmpty()};
    this.onChange = (editorState) => this.setState({editorState});
  }

  onUndo() {
    this.onChange(EditorState.undo(this.state.editorState));
  }

  onRedo() {
    this.onChange(EditorState.redo(this.state.editorState));
  }

  render() {
    return (
      <div>
      <button onClick={this.onUndo.bind(this)}>undo</button>
      <button onClick={this.onRedo.bind(this)}>Redo</button>
        <Editor editorState={this.state.editorState} onChange={this.onChange} />
        </div>
    );
  }
}

ReactDOM.render(
  <MyEditor />,
  document.getElementById('root')
);

Upvotes: 2

Simon
Simon

Reputation: 628

You already found out why (you needed to reference the editorState variable correctly), but I still want to give you this on the way:

You should change your onClick method as followed:

onClick() {
  this.setState({
    editorState: EditorState.undo(editorState)
  })
}

to

onClick() {
  this.onChange(EditorState.undo(this.state.editorState));
}

For DraftJS, it is usually "bad practise" if you try to change the editorState via a method other than onChange.

If you do any change to the editorState, just trigger onChange once you're done.

Also, do you know Draft JS Plugins already? It's a wonderful collection of very useful plugins for DraftJS also including undo/redo buttons!

https://www.draft-js-plugins.com/

Upvotes: 4

Related Questions