如何在React版TinyMCE工具栏中添加自定义组件?
在React的TinyMCE工具栏中添加自定义组件的可行方案
要给React版TinyMCE的工具栏加自定义组件(比如你提到的div或<TestComponent />),有两种实用方法:
方法一:用TinyMCE的addToolbarItemAPI挂载组件
利用TinyMCE官方提供的自定义工具栏项API,在回调里创建DOM容器,再把React组件渲染进去,同时做好销毁清理避免内存泄漏。
import React from 'react'; import { Editor } from '@tinymce/tinymce-react'; import ReactDOM from 'react-dom/client'; // React 18+适用 // React 17及以下请导入:import ReactDOM from 'react-dom'; // 自定义组件示例 const TestComponent = () => ( <div style={{ padding: '0 8px', borderLeft: '1px solid #ccc' }}> <ul style={{ margin: 0, paddingLeft: '16px' }}> <li>Test 1</li> <li>Test 2</li> </ul> </div> ); const MyEditor = () => { return ( <Editor apiKey="你的TinyMCE API密钥" init={{ toolbar: 'undo redo | customComponent', // 把自定义项加入工具栏配置 setup: (editor) => { editor.ui.registry.addToolbarItem('customComponent', { render: () => { const container = document.createElement('div'); // React 18+用createRoot渲染组件 const root = ReactDOM.createRoot(container); root.render(<TestComponent />); // 编辑器销毁时卸载组件,防止内存泄漏 editor.on('destroy', () => { root.unmount(); }); return container; } }); } }} /> ); }; export default MyEditor;
方法二:直接操作DOM挂载组件
如果不想依赖TinyMCE的UI注册API,也可以等编辑器初始化完成后,找到工具栏的DOM节点,直接把React组件挂载到末尾。
import React, { useEffect, useRef } from 'react'; import { Editor } from '@tinymce/tinymce-react'; import ReactDOM from 'react-dom/client'; const TestComponent = () => ( <div style={{ padding: '0 8px', borderLeft: '1px solid #ccc' }}> <ul style={{ margin: 0, paddingLeft: '16px' }}> <li>Test 1</li> <li>Test 2</li> </ul> </div> ); const MyEditor = () => { const editorRef = useRef(null); const componentRootRef = useRef(null); useEffect(() => { const editor = editorRef.current?.editor; if (!editor) return; const handleInit = () => { // 找到TinyMCE的工具栏容器(默认类名为tox-toolbar__primary) const toolbar = editor.getContainer().querySelector('.tox-toolbar__primary'); if (!toolbar) return; // 创建组件容器并添加到工具栏末尾 const container = document.createElement('div'); toolbar.appendChild(container); // 渲染React组件 componentRootRef.current = ReactDOM.createRoot(container); componentRootRef.current.render(<TestComponent />); }; editor.on('init', handleInit); // 组件卸载时清理 return () => { editor.off('init', handleInit); if (componentRootRef.current) { componentRootRef.current.unmount(); } }; }, []); return ( <Editor apiKey="你的TinyMCE API密钥" ref={editorRef} init={{ toolbar: 'undo redo' // 正常配置原有工具栏项 }} /> ); }; export default MyEditor;
注意事项
- 替换代码中的
你的TinyMCE API密钥为实际密钥(本地部署可省略,但官方推荐使用) - 自定义组件的样式可以根据需求调整,避免和TinyMCE默认样式冲突
- React 17及以下版本需将
createRoot替换为ReactDOM.render(<TestComponent />, container),清理时用ReactDOM.unmountComponentAtNode(container)
内容的提问来源于stack exchange,提问作者badcoder
相关产品推荐
相关产品推荐

