Ally Jr
Ally Jr

Reputation: 1075

Draft js saving and rendering or displaying content

The question is: How do I save draft-js content as html and later render the content (which is a html string at this point) on the page.

Thought I'd share what I've learnt.

Please find in the solution one approach to saving and rendering content using draft.js.

Also please post your own solutions so that we can all learn.

Upvotes: 3

Views: 5347

Answers (3)

Ganesh Lamichhane
Ganesh Lamichhane

Reputation: 221

 

Draft.js content is typically stored as a serialized JSON object that includes information about text blocks, inline styles, and entities. To display this content in webpage, you need to convert it back to HTML or plain text.

Draft.js does not provide an out-of-the-box solution for this conversion, but there are several libraries available that can help. A popular choice is draftjs-to-html.

import draftToHtml from 'draftjs-to-html';

const rawContent = typeof storyBehind === 'string' ? JSON.parse(storyBehind) : storyBehind; //convert to raw object If storyBehind is a serialized JSON string instead of a raw object
const text=draftToHtml(rawContent)

Here, storyBehind is a draft. JS content stored in DB. Now you can display text as,

<p dangerouslySetInnerHTML= __html:text></p>

Upvotes: 0

Jeremy Iglehart
Jeremy Iglehart

Reputation: 4479

There is a great example in the documentation demonstrating this process. Here is a link to the source code on Github.

Essentially the code snippet you're looking for is this:

const sampleMarkup =
  '<b>Bold text</b>, <i>Italic text</i><br/ ><br />' +
  '<a href="http://www.facebook.com">Example link</a>';

const blocksFromHTML = convertFromHTML(sampleMarkup);
const state = ContentState.createFromBlockArray(blocksFromHTML);

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

The utility function is called convertFromHTML

Upvotes: 2

Ally Jr
Ally Jr

Reputation: 1075

after endless searching and scouring the internet for how to use draft.js for a blog we are building, i thought I would share what I learnt. Draft.js is AMAZING but its not very clear how to render the data after saving since there is no official render solution.

Here is an abstract demo on how one could do this.

Plugins user were draft-js, draft-convert, react-render-html. Database used was mongo

create post:

import React, {Component} from 'react';
import {
    Block,
    Editor,
    createEditorState
} from 'medium-draft';
import { convertToHTML } from 'draft-convert';

class PostEditor extends Component {
    constructor(props) {
        super(props);

        this.state = {
            stateEditor: createEditorState()
        }

        this.onChange = (editorState) => {
            this.setState({ editorState });
        };

        this.publishPost = this.publishPost.bind(this);
    }
    publishPost() {
        // turn the state to html
        const html = convertToHTML(this.state.editorState.getCurrentContent());

        const post = {
            content: html,
            createdAt: new Date()
            // more stuff...
        }

        // post the data to you mongo storage.
    }
    render() {
        // get the editorState from the component State
        const { editorState } = this.state;
        return (
            <div>
                <Editor
                    ref="editor"
                    editorState={editorState}
                    placeholder="Write your blog post..."
                    onChange={this.onChange} />
                <div>
                    <button onClick={this.publishPost} type="button">Submit</button>
                </div>
            </div>
        )
    }
}

render the post:

import React, { Component } from 'react';
import renderHTML from 'react-render-html';

class PostArticle extends Component {
    constructor(props) {
        super(props);

        this.state = {
            text: null
        }
    }
    componentWillMount() {
        // get the data from the database
        const post = getMyBlogPostFunction(); // replace getMyBlogPostFunction with own logic to fetch data
        this.setState({ text: post.content })
    }
    render() {
        return (
            <div className='article-container'>
                {renderHTML(this.state.text)}
            </div>
        )
    }
}

Note: Html script tags have been escaped.

While the solution above might not be perfect for every use case, I hope someone can find it useful for basic usage.

Disclaimer: I am not liable for any damage, or harm caused through the use of the above code.

Upvotes: 3

Related Questions