【问题标题】:Using React with uncontrolled third-party components将 React 与不受控制的第三方组件一起使用
【发布时间】:2016-10-09 23:51:13
【问题描述】:

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

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

我想为 HTML、CSS 和 JS 面板使用 Microsoft 的 Monaco editor 来获得语法高亮和自动完成功能。

我已经抽象出一个通用的 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() 以从每个面板中提取全文并生成预览。

然而,这在 React 中变得很尴尬,因为 run() 方法不能调用子组件实例上的方法。

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

我能想到的唯一其他方法是将“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();
    // ...
  }
}

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

【问题讨论】:

    标签: javascript reactjs monaco-editor


    【解决方案1】:

    您可以结帐react-monaco-editor

    这将满足您的所有要求!尤其是getting value from the editor instance

    如果不是这样,请在编辑器组件中声明一个函数并使用ref 从其他组件调用该函数。

    希望对你有帮助!

    【讨论】:

    • 这里的一般原则是您可以使用ref 来获取对组件实例的引用。这可以公开特定于实例的方法,例如getValue()。这有点违背 React 的数据流模型的精神,但确实很方便!
    猜你喜欢
    • 2020-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-29
    • 1970-01-01
    • 1970-01-01
    • 2021-01-11
    相关资源
    最近更新 更多