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

React项目中Monaco Editor删除异常:每次删除2个字符求助

解决React中Monaco Editor一次删除两个字符的问题

这个问题大概率是编辑器内容变更事件与React状态更新形成循环触发,导致删除操作被执行了两次。结合你的代码,给出以下修复方案:

1. 用Ref保存编辑器实例

将编辑器实例存入React Ref,避免引用丢失或重复创建,同时方便组件卸载时清理资源:

import { useEffect, useRef } from 'react';

// ...

const monacoEditorRef = useRef(null);

useEffect(() => {
    const editorContainer = document.getElementById('monaco-mermaid');
    const monacoEditor = monaco.editor.create(editorContainer, {
        language: 'mermaid',
        minimap: { enabled: false },
        fontWeight: '600',
        fontSize: '14px',
        overviewRulerLanes: 0,
        quickSuggestions: false,
    });
    monacoEditorRef.current = monacoEditor;

    // 组件卸载时销毁编辑器,避免内存泄漏
    return () => {
        monacoEditor.dispose();
    };
}, []);

2. 避免循环触发变更事件

如果handleChangeCode会将新值同步回父组件状态,再通过props重新设置编辑器内容,就会触发二次变更。需根据组件类型调整逻辑:

非受控组件(编辑器自主管理内容)

简化变更事件逻辑,去掉不必要的防抖逻辑(你的setTimeout可能加剧冲突):

useEffect(() => {
    if (!monacoEditorRef.current) return;

    const handleContentChange = () => {
        const newValue = monacoEditorRef.current.getValue();
        handleChangeCode(newValue);
    };

    const editor = monacoEditorRef.current;
    const disposable = editor.onDidChangeModelContent(handleContentChange);

    return () => {
        disposable.dispose(); // 移除事件监听
    };
}, []);

受控组件(外部状态驱动编辑器内容)

添加外部值变化的监听,同时通过值对比避免循环触发:

// 假设外部传入的内容为props.code
const { code, handleChangeCode } = props;

// 外部值变化时,同步更新编辑器
useEffect(() => {
    if (!monacoEditorRef.current) return;
    const editor = monacoEditorRef.current;
    if (editor.getValue() !== code) {
        editor.setValue(code);
    }
}, [code]);

// 编辑器内容变化时,同步更新外部状态
useEffect(() => {
    if (!monacoEditorRef.current) return;

    const handleContentChange = () => {
        const newValue = monacoEditorRef.current.getValue();
        if (newValue !== code) {
            handleChangeCode(newValue);
        }
    };

    const editor = monacoEditorRef.current;
    const disposable = editor.onDidChangeModelContent(handleContentChange);

    return () => {
        disposable.dispose();
    };
}, [code, handleChangeCode]);

3. 检查初始化逻辑

确认initEditor(monaco)不会修改编辑器内容或绑定额外的变更事件,避免与现有逻辑冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 08:55:23