将React与不受控制的第三方组件一起使用

时间:2016-10-09 15:01:21

标签: javascript reactjs monaco-editor

我想使用React创建一个类似于JSFiddle的UI:

  • HTML,CSS和JS的面板
  • 预览面板
  • 更新预览的单个“运行”按钮

我想将Microsoft的Monaco editor用于HTML,CSS和JS面板,以获得语法高亮和自动完成功能。

我抽象出了一个通用的MonacoEditor组件。我的组件层次结构如下所示:

<Root>
  <div>HTML <MonacoEditor /></div>
  <div>CSS <MonacoEditor /></div>
  <div>JS <MonacoEditor /></div>
  <button onClick={this.run}>Run</button>
  <PreviewPanel />
</Root>

如果我在Vanilla JS中实现此UI,run()方法将在每个Monaco实例上调用getValue()以从每个面板中提取全文并生成预览。

然而,由于run()方法不能在子组件的实例上调用方法,因此这对于React来说变得很尴尬。

一个解决方法是让MonacoEditor拥有onUpdate道具,每次击键都会被触发。当单击“运行”按钮时,Root组件可以存储每个面板的临时内容。如果每个编辑器都是<textarea>,我就可以这样做。但这对摩纳哥来说并非首发。在每次击键时序列化编辑器的文本会使它变得非常慢。

我能想到的另一种方法是将“getter setter”传递给MonacoEditor组件,例如:

class Root extends React.Component {
  render() {
    return (
      <div>
        <MonacoEditor setGetter={getter => this.getHTML=getter} />
        <MonacoEditor setGetter={getter => this.getCSS=getter} />
        <MonacoEditor setGetter={getter => this.getJS=getter} />
        <button onClick={() => this.run()}>Run</button>
        <PreviewPanel />
      </div>
    );
  }

  run() {
    const html = this.getHTML();
    const css = this.getCSS();
    const js = this.getJS();
    // ...
  }
}

但这感觉非常尴尬,与单向数据绑定的想法背道而驰。是否有更好,更惯用的方法?

1 个答案:

答案 0 :(得分:2)

You can checkout react-monaco-editor.

This will satisfy all your requirements! Especially getting value from the editor instance.

If not this, declare a function inside the editor component and use ref to call that function from other components.

Hope it helps!