50 行代码 React Hooks 中使用 wangEditor 富文本编辑器

6,323 阅读3分钟

更新

wangEditor V5 已正式发布,查看官网

前言

50 行代码 Vue3 中使用富文本编辑器 之后,继续使用 wangEditor V5 实现 React 富文本编辑器。wangEditor V5 官方提供 React 组件,使用非常简单。

wangEditor V5 正在公开测试中,有问题和建议可以提交到 github issue 。

【注意】编辑器后续可能继续升级,API 和配置或许会调整。所以问题请及时查阅文档,不要仅依赖本文。

安装

使用 create-react-app 创建一个 React 开发环境,然后安装 wangEditor 必要的包

yarn add @wangeditor/editor
yarn add @wangeditor/editor-for-react

创建编辑器

写代码

创建 React 组件 MyEditor.js,代码如下,大约 50 行,逻辑也非常简单。(源码在文章最后)

import React, { useState, useEffect } from 'react'
import { Editor, Toolbar } from '@wangeditor/editor-for-react'
import '@wangeditor/editor/dist/css/style.css'

function MyEditor() {
    const [editor, setEditor] = useState(null) // 存储 editor 实例
    const [html, setHtml] = useState('<p>hello</p>')

    // 模拟 ajax 请求,异步设置 html
    useEffect(() => {
        setTimeout(() => {
            setHtml('<p>hello&nbsp;<strong>world</strong>.</p>\n<p><br></p>')
        }, 1500)
    }, [])

    const toolbarConfig = { }
    const editorConfig = {
        placeholder: '请输入内容...',
    }

    // 及时销毁 editor ,重要!
    useEffect(() => {
        return () => {
            if (editor == null) return
            editor.destroy()
            setEditor(null)
        }
    }, [editor])

    return (
        <>
            <div style={{ border: '1px solid #ccc', zIndex: 100, marginTop: '15px'}}>
                <Toolbar
                    editor={editor}
                    defaultConfig={toolbarConfig}
                    mode="default"
                    style={{ borderBottom: '1px solid #ccc' }}
                />
                <Editor
                    defaultConfig={editorConfig}
                    value={html}
                    onCreated={setEditor}
                    onChange={editor => setHtml(editor.getHtml())}
                    mode="default"
                    style={{ height: '500px' }}
                />
            </div>
            <div style={{ marginTop: '15px' }}>
                {html}
            </div>
        </>
    )
}

export default MyEditor

运行

把这个组件引入到 App.js 中,即可生成一个功能齐全的富文本编辑器。
当编辑器内容发生变化时,onChange 会实时更新 value ,获取最新的内容。

image.png

注意事项

  • onCeated 时记录 editor 实例,方便后续执行 API
  • 组件销毁时,及时销毁 editor 防止内存泄漏

配置

编辑器配置

上文代码中只配置了 placeholder 作为示例。它还支持 readOnly autoFocus maxLength 等配置,可参考文档

const editorConfig = {
    placeholder: '请输入内容...',
    readOnly: true,
    autoFocus: false,

    // 继续其他配置
}

工具栏配置

如果你想修改工具栏的菜单,如隐藏某些菜单,重新排序分组,就可以使用该配置。支持 toolbarKeys 和 excludeKeys,可参考文档

const toolbarConfig = {
    toolbarKeys: [ /* 显示哪些菜单,如何排序、分组 */ ],
    excludeKeys: [ /* 隐藏哪些菜单 */ ],
}

菜单配置

如果你想对某个菜单进行配置,例如配置颜色、字体、字号,配置上传图片的 API 地址等,可以使用菜单配置。具体参考文档

const editorConfig = {
    // 编辑器配置,如 placeholder onChange ...

    // 所有的菜单配置,都要在 MENU_CONF 属性下
    MENU_CONF: {
        // 配置字号
        fontSize: [ ... ],

        // 配置上传图片
        uploadImage: { ... },

        // 继续其他菜单配置
    }
}

API

wangEditor 提供了丰富的 API ,可以帮助你进行任何编辑器操作。可参考文档

  • 配置相关的 API
  • 内容处理相关的 API
  • 节点操作相关的 API
  • 选区操作相关的 API
  • 自定义事件的 API

我们在上述代码中,已经在 onCreated 时记录了 editor 实例,所以想使用 API ,直接在 editor 上执行即可。

function insertText() {
    if (editor == null) return
    editor.insertText(' hello ')
}

function printHtml() {
    if (editor == null) return
    console.log(editor.getHtml())
}

return <>
    <div>
        <button onClick={insertText}>insert text</button>
        <button onClick={printHtml}>print html</button>
    </div>
    
    <div style={{ border: '1px solid #ccc', zIndex: 100}}>
        <Toolbar ... />
        <Editor ... />
    </div>
</>

总结

本文源码在这里

wangEditor V5 正在公开测试中,有问题和建议可以提交到 github issue 。