React を使用して JSFiddle に似た UI を作成したいと思います。
- HTML、CSS、JS のパネル
- プレビュー パネル
- プレビューを更新する単一の「実行」ボタン
HTML、CSS、および JS パネルにMicrosoft のMonaco エディターを使用して、シンタックス ハイライトとオートコンプリートを取得したいと考えています。
一般的な MonacoEditor コンポーネントを抽象化しました。私のコンポーネント階層は次のようになります。
<Root>
<div>HTML <MonacoEditor /></div>
<div>CSS <MonacoEditor /></div>
<div>JS <MonacoEditor /></div>
<button onClick={this.run}>Run</button>
<PreviewPanel />
</Root>
この UI を Vanilla JS で実装した場合、run()
メソッドは各 Monaco インスタンスを呼び出しgetValue()
て、各パネルから全文を抽出し、プレビューを生成します。
run()
ただし、メソッドは子コンポーネントのインスタンスでメソッドを呼び出すことができないため、React では扱いにくくなります。
1 つの回避策は、すべてのキーストロークで発生するプロップをMonacoEditor
に持たせることです。onUpdate
コンポーネントはRoot
、「実行」ボタンがクリックされたときの各パネルの仮の内容を保存できます。これは、各エディターが<textarea>
. しかし、モナコでは先発ではない。キーストロークごとにエディターのテキストをシリアル化すると、使用できないほど遅くなります。
私が考えることができる他の唯一のアプローチは、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();
// ...
}
}
しかし、これは非常にぎこちなく、一方向のデータバインディングの考え方に反しています。より良い、より慣用的なアプローチはありますか?