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

TinyMCE tinycomments_create函数无法读取更新后的state值求助

解决TinyMCE Comments插件create函数无法读取最新选中文本的问题

问题核心是闭包陷阱:tinycomments_create在组件首次渲染时被传入Editor的init配置,此时它捕获的是highlightedText的初始值(空字符串)。后续用户选中文本更新state时,这个函数的闭包并没有更新,所以始终读不到最新值。

直接用useRef来保存选中文本的最新值就能解决,因为ref的current属性是可变的,不受闭包限制:

步骤1:引入并初始化useRef

把原来的useState替换(或补充)为useRef:

import { useState, useRef } from 'react';
// ...其他导入

function Editor() {
  // 用ref保存最新选中的文本
  const highlightedTextRef = useRef("");
  // 如果还需要state做其他渲染用,可以保留useState,同时更新ref
  // let [highlightedText, setHighlightedText] = useState("");

  // ...
}

步骤2:更新MouseUp事件的逻辑

在编辑器的MouseUp事件里,更新ref的current值:

init_instance_callback: (editor) => {
  editor.on("MouseUp", function (e) {
    const selectedText = e.view.getSelection().toString();
    if (selectedText !== "") {
      highlightedTextRef.current = selectedText;
      // 如果保留了state,同步更新:setHighlightedText(selectedText);
    }
  });
},

步骤3:修改tinycomments_create函数

在函数里读取highlightedTextRef.current而不是原来的state变量:

const tinycomments_create = (req, done, fail) => {
  const { content, createdAt } = req;
  // 读取ref的最新值
  const currentHighlightedText = highlightedTextRef.current;

  console.log("选中的文本:", currentHighlightedText);

  fetch("my-backend-endpoint", {
    method: "POST",
    body: JSON.stringify({
      content,
      createdAt,
      highlightedText: currentHighlightedText,
    }),
    headers: {
      Accept: "application/json",
      "Content-Type": "application/json",
    },
  })
  // ...后续逻辑不变
};

为什么之前的useCallback/useEffect没用?

因为TinyMCE实例初始化后,不会自动监听tinycomments_create函数的引用变化。就算用useCallback更新了函数引用,Editor组件也不会重新把新函数传给已初始化的TinyMCE实例,除非强制重新渲染编辑器(比如加key),但这样成本太高。而用ref的方式,不需要改变函数引用,就能直接拿到最新值,是最简洁的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 10:32:12