简体   繁体   中英

I can't get the html output from draft-js?

I've been playing around with draft-js by Facebook, but I can't actually figure out how to get the html output of the editor. The console.log in the following example outputs some _map properties, but they don't seem to contain my actual content?

class ContentContainer extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          value: '',
          editorState: EditorState.createEmpty()
        };
        this.onChange = (editorState) => this.setState({editorState});
        this.createContent = this.createContent.bind(this);
      }

      createContent() {
        console.log(this.state.editorState.getCurrentContent());
      }

      render() {
        const {editorState} = this.state;
        const { content } = this.props;
        return (
          <Template>
            <br /><br /><br />
            <ContentList content={content} />
            <div className="content__editor">
              <Editor editorState={editorState} onChange={this.onChange} ref="content"/>
            </div>
            <FormButton text="Create" onClick={this.createContent.bind(this)} />
          </Template>
        );
      }
    }

There is a handy library I used, draft-js-export-html . Import the library and you should be able to see HTML once you invoke the function, stateToHTML :

console.log(stateToHTML(this.state.editorState.getCurrentContent()));

I'm pretty new to React so hopefully this works for you. I looked under the hood of contentState and there is a fair bit going on there that makes using a library to parse out the entities that much more enticing.

The author, sstur, answers a tangentially-related question where I learned about his libraries.

Ewan. I am also playing with Draft.js and came across the same problem. Actually, Victor has provided a great solution.

Here are two libraries that I found. The one mentioned by Victor has more stars on GitHub.

https://github.com/sstur/draft-js-export-html

https://github.com/rkpasia/draft-js-exporter

I just want to add that there is a way to print out the content (in JSON format) without using an external library. It is documented under the Data Conversion session.

Here is how I print out user input using the "convertToRaw" function

console.log(convertToRaw(yourEditorContentState.getCurrentContent())); 

Make sure you imported the convertToRaw function from Draft.js by writing:

import { convertFromRaw, convertToRaw } from 'draft-js';

Here is a great blog written by rajaraodv named How Draft.js Represents Rich Text Data . It explained data conversion in detail.

有 readonly 属性可以只生成 HTML:

<Editor editorState={editorState} readOnly/>

If not willing to add another library to your code, @farincz's approach can work well.

<Editor editorState={this.state.editorState} readOnly/>

The editor state can be directly stored in your storage layer and when you are rendering it to the DOM it is easily available and can help in editing.

By clicking on the text you can make it editable, or bind that click with an edit button. You cannot directly bind click to 'Editor' component, but you can have it on the wrapper containing the 'Editor'.

<div className="editor" onClick={this.editContent.bind(this)}>
  <Editor
    editorState={this.state.editorState}
    onChange={this.onChange}
    handleKeyCommand={this.handleKeyCommand}
    readOnly={this.state.edit}
  />
</div>

Just add 'edit' to your state as true, making sure that readOnly is true (you can make the name 'edit' of the state more obvious, if it is confusing).

this.state = {
 editorState: EditorState.createEmpty(), 
 edit: true
};

Finally change the value of 'edit' to false on click

editContent() {
  this.setState({
    edit: false
  })
}

To expand on the libraries shared above, here's another good one : draftjs-to-html

It converts raw editor state (JSON object) into plain HTML.

import draftToHtml from 'draftjs-to-html';
import {convertToRaw} from "draft-js";

const rawContentState = convertToRaw(editorState.getCurrentContent());
const markup = draftToHtml(rawContentState);

The most suitable package to convert to HTML and from HTML is draft-convert

However, you should be aware to use the Advanced usage to be able to convert links and to customize the convert process:

const htmlResult = convertToHTML({
  entityToHTML: (entity, originalText) => {
    if (entity.type === 'LINK') {
      return <a href={entity.data.url}>{originalText}</a>;
    }
    return originalText;
  }
})(editorState.getCurrentContent());


const contentState = convertFromHTML({
    htmlToEntity: (nodeName, node, createEntity): any | void => {
        if (nodeName === 'a') {
            return createEntity(
                'LINK',
                'MUTABLE',
                {url: node.href}
            )
        }
    }
})(htmlInput);

The way I did it was:

Store the editorState as an html string editorState.toString('html') and then when showing the output, use <div className="content__editor" dangerouslySetInnerHTML={{__html: this.state.editorState}}>

This is pretty handy, if you just simply want to output the content of draft-js without adding too much HTML markup, passing it as props just like you would do with a stateless functional component.

Also follow the React's guidelines to prevent XSS attack on dangerouslySetInnerHTML

https://reactjs.org/docs/dom-elements.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM