Simple and easy way to display Draft.js content

When looking through Draft.js docs there is much talk about how you can modify the editor's state in many different ways. Draft.js also provides us with convertToRaw function that we can use to convert the state to plain JSON. But there is little information on how to actually display Draft.js content. Do you need to implement some custom parsing for the state JSON? Or is there some existing library or way to take the state JSON and display it nicely?

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

This is what the docs say about displaying the content: "Note that the Draft library does not currently provide utilities to convert to and from markdown or markup, since different clients may have different requirements for these formats. We instead provide JavaScript objects that can be converted to other formats as needed."

So Draft.js provides utility functions for converting the state to raw JS (convertToRaw) and raw JS to ContentState object (convertFromRaw) but not to markdown or markup. This has led to birth of separate markdown/markup converting libraries. I wrote a post on how to use one of these libraries to display Draft.js content as HTML.

Using the Draft editor for display

Converting the state JSON to a markdown/markup is not however the only way to display your state. Another way is to initialise a Draft.js editor with the saved state JSON and put the editor into readOnly mode. This way the editor component will handle all the styling and there will less likely be bugs or inconsistencies in the styling of the contents than there would be when using external converting libraries because the converting is done by Draft.js itself. Here is an example on how to do that.

For the purposes of this example we are going to load the stored state from a JSON file. Our storedState.json file looks like this:

1{
2  "blocks": [
3    {
4      "key": "8i090",
5      "text": "Hello CodePulse!",
6      "type": "unstyled",
7      "depth": 0,
8      "inlineStyleRanges": [
9        {
10          "offset": 0,
11          "length": 16,
12          "style": "BOLD"
13        }
14      ],
15      "entityRanges": [],
16      "data": {}
17    },
18    {
19      "key": "42ncd",
20      "text": "This text should be underlined.",
21      "type": "unstyled",
22      "depth": 0,
23      "inlineStyleRanges": [
24        {
25          "offset": 0,
26          "length": 31,
27          "style": "UNDERLINE"
28        }
29      ],
30      "entityRanges": [],
31      "data": {}
32    },
33    {
34      "key": "327r6",
35      "text": "And this text should be italic.",
36      "type": "unstyled",
37      "depth": 0,
38      "inlineStyleRanges": [
39        {
40          "offset": 0,
41          "length": 31,
42          "style": "ITALIC"
43        }
44      ],
45      "entityRanges": [],
46      "data": {}
47    }
48  ],
49  "entityMap": {}
50}

Here is the actual component that we use to display the stored state:

1import React from "react";
2import ReactDOM from "react-dom";
3import { Editor, EditorState, convertFromRaw } from "draft-js";
4import storedState from "./storedState.json";
5
6class App extends React.Component {
7  render() {
8    const contentState = convertFromRaw(storedState);
9    const editorState = EditorState.createWithContent(contentState);
10    return (
11      <div className="App">
12        <Editor editorState={editorState} readOnly={true} />
13      </div>
14    );
15  }
16}
17
18const rootElement = document.getElementById("root");
19ReactDOM.render(<App />, rootElement);

On the lines 3 and 4 we import everything related to Draft.js and also the stored state (again, we import the state from a file to keep this example simple).

In the render method we create a contentState object by passing the JS object for the state as a parameter for convertFromRaw method (line 8). Once we have the contentState object we create an editorState object out of it with EditorState.createWithContent (line 9).

Finally we render our Editor component with the editorState we just created (line 12). We also set readOnly={true} for the editor component so it is displayed nicely and the content cannot be modified.

Draft.js editor displaying content in readOnly mode

You can find a codesandbox for this example here.

Conclusion

As we saw using the Draft editor component with readOnly set to true, it is quite simple to display Draft.js content. You don't necessarily need to convert the state to e.g. HTML or markdown in order to display it. I must add though that I am not sure if this is the most optimal way of displaying Draft.js content. What I can say is that I have used this approach in projects that are in production and it has worked well for me.

If you have an idea of another approach or have used a different solution for displaying Draft.js content, please leave a comment below! I would like to hear from you! And of course if you have any questions or thoughts be sure to comment them below too!


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