在react-split中嵌入react-ace

问题描述

react-ace中嵌入react-split时出现奇怪的行为。在这里,我在两个窗格中嵌入了两个编辑器,并在第一个窗格的第一行中键入let x = "this line got scrolled left"

enter image description here

在键入代码时,只要我在编辑器之前的黄色标题div中击中文本的最右边,Ace就会在我键入时开始向左滚动行。随后,我可以将文本滚动回到视图中,但是Ace不允许我将光标定位在编辑器中此点的右侧。

如果我从每个窗格中删除前面的黄色标题,那么Ace的行为就好像该滚动点是第一个字符,因此从不让我在键入时看到这些字符。

好像浏览器认为窗格具有一个宽度,而Ace认为其具有另一宽度,该宽度是用编辑器在窗格中显示其他任何内容所需的最小宽度。

这是我的React,使用nextjs实现:

import Split from 'react-split'
import AceEditor from 'react-ace'
import 'brace/mode/javascript'

export default function Home() {
  return (
    <main className="outermost">
      <Split
        className="my_split"
        sizes={[50,50]}
        minSize={100}
        expandToMin={false}
        gutterSize={10}
        gutteralign="center"
        snapOffset={0}
        direction="horizontal"
      >
        <CodePane id="left_pane" />
        <CodePane id="right_pane" />
      </Split>
    </main>
  )
}

function CodePane(props: {id: string}) {
  return <div id={props.id} className="code_pane">
    <div className="pane_header">Right code margin |</div>
    <AceEditor
      name={props.id + "_editor"}
      mode="javascript"
      height="100%"
      width="100%"
    />
  </div>;
}

这是我的CSS:

body {
  padding: 0;
  margin: 0;
}

* {
  Box-sizing: border-Box;
}

.outermost {
  width: 100%;
  height: 100vh;
  background-color: darkblue;
  padding: 20px;
}

.my_split {
  display: flex;
  flex-direction: row;
  width: 100%;
  height: 100%;
  background-color: lightgray;
}

.pane_header {
  background-color: yellow;
  width: 100%;
  height: 20px;
}

.code_pane {
  height: 100%;
  background-color: red;
}

.split,.gutter.gutter-horizontal {
  height: 100%;
}

我尝试实施react-split docs中的CSS建议。我还用float:left实现了这一点,并遇到了同样的问题。我发现文档难以理解,可能是我做错了。

我在CSS中做错了吗?感谢您提供的任何帮助。

(注意:我意识到Ace提供了一种拆分编辑器的方法,但这不是我要在我的应用程序中尝试的方式。我只是出于演示目的使用两个编辑器。)

解决方法

afk-mario提供了an answer on GitHub,我将对其进行总结。

Ace编辑器根据窗口resize事件重新计算其大小,因此我可以通过手动发出此事件来强制重新计算。

将以下内容添加到React的componentDidMount()和Split的onDragEnd()处理程序中即可解决问题:

window.dispatchEvent(new Event('resize'));