You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 04:01:56