How to store Draft.js content

Earlier I wrote about Draft.js and how to display editor content as HTML. Most often just showing the current editor content as HTML is not sufficient and we need to store the editor content somewhere for example to a database. The HTML representation of the editor content can of course be stored to a database, but that is not the best option.

I just published a class where I teach more about Draft.js. Best part is that you can get it for free! Read more.

Draft.js comes with convertToRaw method that takes in a ContentState object and returns the given ContentState as a raw javascript object. This object can then be stored to a database or wherever you need to store your application’s data.

Then when we need to load the data from the database, we get the raw javascript object and we make use of another method provided by Draft.js, convertFromRaw. This method takes in a raw javascript object and returns corresponding ContentState object. You can then use this ContentState object to populate your Draft.js editor with your content.

Saving and loading Draft.js content

Let’s see an example:

1import React from "react";
2import {
3  Editor,
4  EditorState,
5  RichUtils,
6  convertToRaw,
7  convertFromRaw,
8} from "draft-js";
9
10class DraftEditorRawExample extends React.Component {
11  constructor(props) {
12    super(props);
13    this.state = { editorState: EditorState.createEmpty() };
14    this.onChange = (editorState) => {
15      // Convert to raw js object
16      const raw = convertToRaw(editorState.getCurrentContent());
17      // Save raw js object to local storage
18      this.saveEditorContent(raw);
19
20      this.setState({ editorState });
21    };
22  }
23
24  componentDidMount() {
25    // Load editor data (raw js object) from local storage
26    const rawEditorData = this.getSavedEditorData();
27    if (rawEditorData !== null) {
28      const contentState = convertFromRaw(rawEditorData);
29      this.setState({
30        editorState: EditorState.createWithContent(contentState),
31      });
32    }
33  }
34
35  saveEditorContent(data) {
36    localStorage.setItem("editorData", JSON.stringify(data));
37  }
38
39  getSavedEditorData() {
40    const savedData = localStorage.getItem("editorData");
41
42    return savedData ? JSON.parse(savedData) : null;
43  }
44
45  handleKeyCommand(command) {
46    const { editorState } = this.state;
47    const newState = RichUtils.handleKeyCommand(editorState, command);
48    if (newState) {
49      this.onChange(newState);
50      return true;
51    }
52    return false;
53  }
54
55  renderContentAsRawJs() {
56    const contentState = this.state.editorState.getCurrentContent();
57    const raw = convertToRaw(contentState);
58
59    return JSON.stringify(raw, null, 2);
60  }
61
62  render() {
63    return (
64      <div>
65        <h4>Draft js editor</h4>
66        <div className="editor-container">
67          <Editor
68            handleKeyCommand={this.handleKeyCommand.bind(this)}
69            editorState={this.state.editorState}
70            onChange={this.onChange}
71          />
72        </div>
73        <h4>Editor content as raw JS</h4>
74        <pre>{this.renderContentAsRawJs()}</pre>
75      </div>
76    );
77  }
78}
79
80export default DraftEditorRawExample;

Here is a working demo: https://github.com/tumetus/draft-js-to-raw

In the example the component has a Draft.js editor and a pre-element that displays the editor content as raw javascript. It also saves the editor’s content to local storage so that when you refresh the page, the editor is populated with the saved data.

Saving and loading makes use of the convertToRaw and convertFromRaw methods mentioned earlier. So in this example you could also save the data for example to a server, instead of just saving it to local storage. For convenience reasons I made this example to save the data to local storage.

So as we see saving and loading Draft.js editor content is pretty straight forward in the end. If you have any questions or comments feel free to leave your comment below.


Read next:
If you want to learn more, make sure to subscribe on Youtube!

Subscribe to the newsletter