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

Lexical.js NodeTransform仅触发一次:自动校正插件失效求助

问题分析

你的问题核心在于当前的autocorrectTransform仅检查整个TextNode的完整文本是否等于目标词("bikes"/"cars"),而Lexical中一段连续无格式文本会作为单个TextNode存在。当目标词只是文本中的一部分时,自然不会触发替换逻辑。

解决方案

修改autocorrectTransform函数,实现对TextNode内部目标词的检测、节点拆分与替换,具体代码如下:

import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
import { LexicalEditor, TextNode, $splitNode, $insertNodes } from "lexical";
import { useEffect } from "react";
import {
    $createAutocorrectNode,
    AutocorrectNode,
} from "./Nodes/AutocorrectNode";

// 统一管理目标词与替换内容
const CORRECTION_MAP = {
  bikes: "shumi",
  cars: "karthik"
};

function autocorrectTransform(node: TextNode) {
  const textContent = node.getTextContent();
  
  // 遍历所有目标词
  for (const [targetWord, correctedVal] of Object.entries(CORRECTION_MAP)) {
    let index = textContent.indexOf(targetWord);
    while (index !== -1) {
      // 拆分出目标词之前的文本节点
      if (index > 0) {
        $splitNode(node, index);
        node = node.getNextSibling() as TextNode;
      }

      // 拆分出目标词节点
      if (node.getTextContent().length > targetWord.length) {
        $splitNode(node, targetWord.length);
      }

      // 替换目标词为AutocorrectNode
      const replacedNode = node.replace($createAutocorrectNode(correctedVal));
      // 获取剩余文本节点
      const remainingNode = replacedNode.getNextSibling() as TextNode | null;
      
      // 继续检查剩余文本中的目标词
      if (remainingNode) {
        textContent = remainingNode.getTextContent();
        index = textContent.indexOf(targetWord);
        node = remainingNode;
      } else {
        break;
      }

      replacedNode?.select();
    }
  }
}

function useAutocorrect(editor: LexicalEditor) {
  useEffect(() => {
    if (!editor.hasNodes([AutocorrectNode])) {
      throw new Error(
          "AutocorrectNode: AutocorrectNode not registered on editor"
      );
    }
  }, [editor]);

  useEffect(() => {
    const removeTransform = editor.registerNodeTransform(
        TextNode,
        autocorrectTransform
    );

    return () => {
      removeTransform();
    };
  }, [editor]);
}

export default function DictionaryOnHoverPlugin() {
  const [editor] = useLexicalComposerContext();
  useAutocorrect(editor);

  return null;
}
关键修改说明
  • 目标词映射表:用CORRECTION_MAP替代硬编码的if-else,后续扩展词汇更便捷
  • 循环拆分替换:通过$splitNode将TextNode拆分为「目标词前文本」「目标词」「目标词后文本」三部分,单独替换目标词节点
  • 全局匹配支持:嵌套循环处理同一TextNode中的多个目标词,确保所有匹配项都被替换
  • 节点状态维护:拆分后更新当前处理的节点引用,保证后续逻辑正确指向剩余文本
额外优化建议
  • 可以添加词边界检测(比如正则new RegExp(\b${targetWord}\b)),避免误匹配包含目标词的更长单词(如"bikeshed"中的"bikes")
  • 若需要延迟触发(比如输入空格或标点后再替换),可以结合编辑器的onChange事件或监听文本输入的结束状态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 13:01:23