react-draft-wysiwyg富文本组件

2018-09-03  本文已影响0人  Ann_l

目录

react-draft-wysiwyg富文本组件

组件使用背景

ant design 、react、dva、react-draft-wysiwyg

组件使用中遇到的问题

当嵌套组件中使用 react-draft-wysiwyg 的 editor 组件时,当我首次进入编辑页面,id=1的文章时,内容应该显示id=1的内容。返回列表页面,重新进入id=2的文章时,react-draft-wysiwyg 的 editor 组件会保留id=1的文章内容。当我返回列表页面,重新进入id=3的文章时,react-draft-wysiwyg 的 editor 组件会保留id=2的文章内容。

实现富文本组件合理使用有2个方案

1、将 react-draft-wysiwyg的editor直接使用,不要嵌套于其他组件内。
2、如果您将 react-draft-wysiwyg的editor 已经嵌套于其他组件,建议您自行实现该组件内容的实现双向绑定。

1、直接使用editor 范例
//  层级关系(我项目中实现是嵌套组件)
-   EditBlogPage.jsx (当前编辑页)
-     UpdateBlogForm
-         EditorConvertToHTML
-             Editor  
render() {
    const { blog } = this.props;
    const itemBlog = blog.get('itemBlog').toJS();
    const blogBodyEditor = blog.get('blogBodyEditor');
    const contentBlock = htmlToDraft(itemBlog.body);
    const contentState = ContentState.createFromBlockArray(contentBlock.contentBlocks);
    const editorState = EditorState.createWithContent(contentState);
    return (
      <Layout>
        <Layout.Content>
          <Row>
            <Card>
             // 使用 UpdateBlogForm 组件
              <UpdateBlogForm
                optType="edit"
                blogBodyEditor={blogBodyEditor}
                itemBlog={itemBlog}
                handleUpdate={this.handleUpdate} />
             // 使用 EditorConvertToHTML 组件
              <EditorConvertToHTML
                body={itemBlog.body} />
             // 直接使用 react-draft-wysiwyg 的 editor
              <Editor
                editorState={editorState}
                toolbar={{
                  options: ['blockType'],
                  blockType: {
                    inDropdown: false,
                    className: 'bordered-option-classname',
                    options: ['Normal', 'H1', 'H2', 'H3', 'H4', 'H5'],
                  },
                }} />
            </Card>
          </Row>
        </Layout.Content>
      </Layout>
    );
  }
组件使用对比图.png

从上图可以看出,当你直接使用editor 没毛病,完全可以实现您的需求。

2、嵌套组件内使用editor

思路:将传给editor的EditorState 存在state中,就像给input实现双向绑定。

// EditorConvertToHTML 组件
import React, { Component, PropTypes } from 'react';
import { Editor } from 'react-draft-wysiwyg';
import { EditorState, convertToRaw } from 'draft-js';
import draftToHtml from 'draftjs-to-html';
import './editor-to-html.scss';

class EditorConvertToHTML extends Component {
  static propTypes = {
    // 同时在将 EditorState 传入渲染使用
    blogBodyEditor: PropTypes.instanceOf(EditorState),
    changeBody: PropTypes.func,
  }
  constructor(props) {
    super(props);
    if (props.blogBodyEditor) {
      this.state = {
        editorState: props.blogBodyEditor,
      };
    } else {
      this.state = {
        editorState: EditorState.createEmpty(),
      };
    }
    this.onEditorStateChange = this.onEditorStateChange.bind(this);
  }
  componentWillReceiveProps(nextProps) {
    if (nextProps.blogBodyEditor) {
      this.setState({
        editorState: nextProps.blogBodyEditor,
      });
    }
  }

  onEditorStateChange(editorState) {
    this.setState({
      editorState,
    });
    // 关键代码:将更改的 editorState 存入state
    this.props.changeBody(editorState, draftToHtml(convertToRaw(editorState.getCurrentContent())));
  }

  render() {
    const { editorState } = this.state;

    return (
        <Editor
          editorState={editorState}
          onEditorStateChange={this.onEditorStateChange}
          toolbar={{
            options: ['blockType'],
            blockType: {
              inDropdown: false,
              className: 'bordered-option-classname',
              options: ['Normal', 'H1', 'H2', 'H3', 'H4', 'H5'],
            },
          }} />
    );
  }
}

export default EditorConvertToHTML;
上一篇下一篇

猜你喜欢

热点阅读