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.
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!