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

React中按下Enter键传递Lexical编辑器文本内容的问题

问题描述

使用Lexical编辑器时,点击提交按钮能正常传递编辑器文本内容,但按下Enter键提交时返回空字符串。当前实现逻辑是通过TextContentListener监听编辑器内容变化,将值同步到useState的textValue中,计划在Enter键触发时传递该值。

问题原因
  1. React状态更新异步性:setTextValue是异步操作,Enter键触发时可能还未完成状态更新,导致拿到旧值。
  2. 闭包捕获旧值:EnterCommand中注册的KEY_ENTER_COMMAND命令,其回调里的onSubmit是组件初始化时捕获的旧值,后续textValue更新后,该回调并未重新注册,仍使用旧的textValue。
  3. 清空命令时序问题:调用onSubmit()后立刻执行CLEAR_EDITOR_COMMAND,会触发TextContentListener将textValue设为空,进一步加剧状态不同步。
解决方案

方案1:直接从编辑器获取文本(推荐)

绕过React状态,直接在Enter事件中从Lexical编辑器实例获取当前文本,避免状态同步问题。

修改EnterCommand组件:

const EnterCommand = ({ onSubmit = () => {} }) => {
  const [editor] = useLexicalComposerContext();

  useEffect(() => {
    return editor.registerCommand(
      KEY_ENTER_COMMAND,
      enterEvent,
      COMMAND_PRIORITY_HIGH
    );
  }, [editor, onSubmit]); // 添加onSubmit到依赖,确保回调更新

  const enterEvent = (event) => {
    const { shiftKey, key } = event;

    if (key === "Enter" && !shiftKey) {
      event.preventDefault();
      // 直接从编辑器获取当前文本
      const currentText = editor.getTextContent();
      onSubmit(currentText);
      editor.dispatchCommand(CLEAR_EDITOR_COMMAND, undefined);
    }

    return true;
  };

  return null;
};

修改Editor组件调用:

// 移除textValue相关状态同步逻辑,直接传递submit函数
<EnterCommand onSubmit={submit} />
// 按钮也可统一用编辑器直接获取文本
<SubmitButton onSubmit={() => submit(editor.getTextContent())} />

方案2:修复闭包捕获问题

让EnterCommand在onSubmit变化时重新注册命令,确保捕获最新的textValue。

修改EnterCommand组件:

const EnterCommand = ({ onSubmit = () => {} }) => {
  const [editor] = useLexicalComposerContext();

  useEffect(() => {
    return editor.registerCommand(
      KEY_ENTER_COMMAND,
      enterEvent,
      COMMAND_PRIORITY_HIGH
    );
  }, [editor, onSubmit]); // 添加onSubmit到依赖数组

  const enterEvent = (event) => {
    const { shiftKey, key } = event;

    if (key === "Enter" && !shiftKey) {
      event.preventDefault();
      onSubmit();
      editor.dispatchCommand(CLEAR_EDITOR_COMMAND, undefined);
    }

    return true;
  };

  return null;
};

在Editor组件中用useCallback包裹提交回调:

const submitHandler = useCallback(() => {
  submit(textValue);
}, [submit, textValue]);

<EnterCommand onSubmit={submitHandler} />

方案3:使用Ref保存最新值

通过useRef保存最新的textValue,避免闭包捕获旧值。

修改Editor组件:

export default function Editor({ submit = () => {} }) {
  const [textValue, setTextValue] = useState("");
  const textValueRef = useRef("");
  const placeholderRef = useRef(null);
  
  // 同步textValue到ref
  useEffect(() => {
    textValueRef.current = textValue;
  }, [textValue]);

  const initialConfig = {
    namespace: "MyEditor",
    theme,
    onError,
  };

  return (
    <div className="grow pl-2 flex items-end gap-2">
      <div className="bg-gray-200/80 pl-4 p-2 rounded-3xl grow mr-12">
        <div>
          <div className="relative">
            <LexicalComposer initialConfig={initialConfig}>
              {/* 其他插件保持不变 */}
              <TextContentListener
                onChange={(text) => {
                  setTextValue(text.trim() === "" ? "" : text);
                }}
              />
              <EnterCommand onSubmit={() => submit(textValueRef.current)} />
              <SubmitButton onSubmit={() => submit(textValue)} />
            </LexicalComposer>
          </div>
        </div>
      </div>
    </div>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 21:47:34