Search code examples
javascriptreactjsantddraftjsreact-draft-wysiwyg

How to convert react-draft uncontrolled editor content to html?


I'm trying to use react-draft-wysiwyg to edit the data fetched from the server. The problem is that I placed the editor inside the render-prop, so I can’t change editorState, as this causes an infinite loop. I configured the editor as uncontrolled to just get the data from the form.

As I understand it, stateToHTML is not suitable here, since it takes state, but here we have an object. Can you tell me, is there other functions that can convert editor data before sending? Or is it better to choose a different editor instead of draft-js?

The form submit handler is inside onFinish from and-design form. Here is the component listing:

import React, { Component, Fragment } from 'react';
import Line from '../components/Line';
import { Button, Form, Input } from 'antd';
import { SaveOutlined } from '@ant-design/icons';
import { connect } from 'react-redux';
import { Get } from 'react-axios';
import { EditorState } from 'draft-js';
import { Editor } from 'react-draft-wysiwyg';
import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css';
import { stateFromHTML } from 'draft-js-import-html';

class Info extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <Fragment>
        {this.props.lang.lang && (
          <Get url={`${process.env.REACT_APP_API_PORT}api/info/${this.props.lang.lang.info}`}>
            {(error, res, isLoading) => {
              if (error) {
                return (<div>Something bad happened: {error.message} </div>)
              }
              else if (isLoading) {
                return (<div>Loading...</div>)
              }
              else if (res !== null) {
                const { data } = res;
                return (
                  <Fragment>
                    <h1>{data.title}</h1>
                    <Line />
                    <Form
                      layout="vertical"
                      initialValues={{
                        ...data
                      }}
                      onFinish={values => {
                        console.log({
                          ...values,
                          body: values.body,
                        });
                      }}
                    >
                      <Form.Item
                        name="title"
                        label="Title"
                        rules={[{ required: true, message: 'Please enter post title' }]}
                      >
                        <Input placeholder="Please enter post title" />
                      </Form.Item>
                      <Form.Item
                        name="body"
                        label="Text"
                      >
                        <Editor
                          defaultEditorState={EditorState.createWithContent(stateFromHTML(data.body))}
                          wrapperClassName="demo-wrapper"
                          editorClassName="demo-editor"
                        />
                      </Form.Item>
                      <Button
                        type="primary"
                        htmlType="submit"
                        className='save'
                      >
                        <SaveOutlined />
                        <span>Сохранить</span>
                      </Button>
                    </Form>
                  </Fragment>
                );
              }
              return (<div>Default message before request is made.</div>)
            }}
          </Get>
        )}
      </Fragment>
    );
  }
}

const mapStateToProps = state => {
  return {
    lang: state.lang
  }
}

export default connect(mapStateToProps, null)(Info);

Regards.


Solution

  • Solved. There's draftjs-to-html package that parses an object from uncontrolled editor form to html.

    import draftToHtml from 'draftjs-to-html';
    

    ...

    body: draftToHtml(values.body)