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

React-Bootstrap模态框中Ace Editor无法显示数据问题求助

解决React-Bootstrap模态框中Ace Editor不显示数据的问题

核心问题分析

你当前的实现直接通过原生Ace API操作编辑器实例,忽略了React组件生命周期和react-ace组件的状态管理逻辑:

  • 模态框显示时,Ace Editor组件可能未完成挂载,此时调用ace.edit获取的实例不准确
  • 直接修改文档内容会绕过react-ace的状态同步机制,导致视图无法自动更新
  • 编辑器在隐藏容器(模态框初始状态为隐藏)中初始化时,尺寸计算异常,引发渲染失效

修正方案

1. 用react-ace的value属性绑定数据

react-ace提供了value props来直接控制编辑器内容,这是符合React数据流的标准做法,避免直接操作底层DOM实例。

2. 通过Ref获取编辑器实例,在模态框显示后触发更新

模态框从隐藏变为可见时,编辑器容器尺寸发生变化,需要手动触发Ace的尺寸计算和渲染更新。

修改后的代码

状态与逻辑部分

import { useRef, useState, useEffect } from 'react';
import { Modal, Button } from 'react-bootstrap';
import AceEditor from 'react-ace';
import 'ace-builds/src-noconflict/mode-json';
import 'ace-builds/src-noconflict/theme-github';

const [isEditorModalShow, setIsEditorModalShow] = useState(false);
const [editorContent, setEditorContent] = useState('');
const editorRef = useRef(null);

const handlePolicyChange = (value: string) => {
  setEditorContent(value);
};

// 同步政策内容到编辑器
useEffect(() => {
  setEditorContent(policy?.Content || 'test');
}, [policy?.Content]);

// 模态框显示后触发编辑器渲染
useEffect(() => {
  if (isEditorModalShow && editorRef.current) {
    const editor = editorRef.current.editor;
    editor.resize(); // 修正容器尺寸
    editor.renderer.updateFull(); // 强制全量渲染
  }
}, [isEditorModalShow]);

模态框与AceEditor组件部分

<Modal
  show={isEditorModalShow}
  onHide={() => setIsEditorModalShow(false)}
  size="lg"
  centered
  dialogClassName="policy-editor-modal"
>
  <Modal.Header className="header">
    <div>{localize('Policies.AdvancedJSON')}</div>
    <Button className="close" onClick={() => setIsEditorModalShow(false)}>
      <img src={Close} alt="Close" />
    </Button>
  </Modal.Header>
  <Modal.Body className="body">
    <AceEditor
      ref={editorRef}
      width="58vw"
      height="50vh"
      mode="json"
      theme="github"
      name="jsonEditor"
      showPrintMargin={false}
      readOnly={false}
      value={editorContent}
      onChange={handlePolicyChange}
      commands={[
        {
          name: 'beautify',
          bindKey: {
            win: 'Ctrl-Shift-F',
            mac: 'Cmd-Shift-F',
          },
          exec: () => {
            if (editorRef.current) {
              const editor = editorRef.current.editor;
              Beautify.beautify(editor.getSession());
            }
          },
        },
      ]}
      fontSize={12}
      setOptions={{
        showLineNumbers: true,
        useWorker: false,
      }}
    />
  </Modal.Body>
</Modal>

额外说明

  • 避免通过ace.edit(id)直接获取实例,react-ace的ref提供了更可靠的编辑器实例引用
  • resize()是关键操作:模态框显示前编辑器容器处于隐藏状态,Ace无法正确计算尺寸,调用该方法可重新计算容器尺寸并触发渲染
  • 保持React数据流一致性:所有内容更新通过value props和状态管理完成,而非直接操作底层API

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 01:50:25