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

TinyMCE自定义工具栏按钮无法获取更新后的React状态值

问题:React中TinyMCE自定义工具栏按钮无法获取更新后的state值

在React项目中使用TinyMCE编辑器时,自定义工具栏按钮的点击事件始终只能获取到state的初始值,无法访问更新后的值。

示例代码

function App() {
  const [state, setState] = React.useState(0);
  const handleAction = (editor) => {
    console.log("State", state); // 始终获取初始状态
  };
  return (
    <>
      <button onClick={() => setState(state + 1)}>Add me</button>
      <p>State: {state}</p>
      <Editor
        apiKey="XXX"
        init={{
          toolbar: "myCustomToolbarButton",
          setup: (editor) => {
            editor.ui.registry.addButton("myCustomToolbarButton", {
              text: "My Custom Button",
              onAction: (editor) => {
                handleAction(editor);
              }
            });
          }
        }}
      />
    </>
  );
}

复现步骤

  • 点击「My Custom Button」按钮,查看控制台输出。
  • 点击「Add me」按钮更新state值。
  • 再次点击「My Custom Button」,发现仍获取初始状态值。

解决方案

方法一:使用useRef保存最新state值(推荐)

问题根源在于TinyMCE的setup函数仅在编辑器初始化时执行一次,onAction回调会捕获初始的state闭包,后续state更新后无法同步。通过useRef可以保存最新的state值,因为ref的current属性是可变的,不受闭包限制。

function App() {
  const [state, setState] = React.useState(0);
  const stateRef = React.useRef(state);
  
  // 每次state更新时同步ref的current值
  React.useEffect(() => {
    stateRef.current = state;
  }, [state]);

  const handleAction = (editor) => {
    console.log("State", stateRef.current); // 现在能获取最新状态
  };

  return (
    <>
      <button onClick={() => setState(state + 1)}>Add me</button>
      <p>State: {state}</p>
      <Editor
        apiKey="XXX"
        init={{
          toolbar: "myCustomToolbarButton",
          setup: (editor) => {
            editor.ui.registry.addButton("myCustomToolbarButton", {
              text: "My Custom Button",
              onAction: (editor) => {
                handleAction(editor);
              }
            });
          }
        }}
      />
    </>
  );
}

方法二:通过key触发编辑器重新初始化(不推荐)

给Editor组件添加key属性,当state变化时更新key,触发编辑器重新渲染,此时setup函数会重新执行,onAction回调会捕获最新的state。但这种方法会重置编辑器的内容和状态,仅适用于不需要保留编辑器内容的场景。

function App() {
  const [state, setState] = React.useState(0);

  const handleAction = React.useCallback((editor) => {
    console.log("State", state);
  }, [state]);

  return (
    <>
      <button onClick={() => setState(state + 1)}>Add me</button>
      <p>State: {state}</p>
      <Editor
        key={state}
        apiKey="XXX"
        init={{
          toolbar: "myCustomToolbarButton",
          setup: (editor) => {
            editor.ui.registry.addButton("myCustomToolbarButton", {
              text: "My Custom Button",
              onAction: (editor) => {
                handleAction(editor);
              }
            });
          }
        }}
      />
    </>
  );
}

内容的提问来源于stack exchange,提问作者Shivam Verma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 22:30:55