UIkit の Markdown Editor を React コンポーネントにしてみました

Ruby勉強会で開発中のアプリケーションに、Markdownエディタを組み込むことにしました。
Reactもフロントで利用することを検討していまして、”React”, “Markdown”, “Editor”でググると そのまんまreact-markdown-editorがあったりします。

これを利用しても良いのですが、CSSフレームワークにはUIkitを採用していますので、まずはUIkitのコンポーネントとして含まれているMarkdownエディタの採用を検討してみることにしました。
理由としては、デザインの統一感の維持と、機能(左側のテキストエリアで編集し、リアルタイムに右側のプレビューに反映される)点を利用したいことがありました。
しかし、Reactのオライリー本に依ると、このMarkdownエディタコンポーネントはReactから見て「行儀の悪いコンポーネント」に該当するようでした。

Reactコンポーネント化には予想以上に苦戦をしました。

行儀が悪いとは・・・

UIkitのMarkdownエディタは、Markdown専用というわけではなく、HTMLで編集することもできます。というかHTMLエディタで、Markdownでも記述できるという方が正しいかもしれません。

このコンポーネントを利用する際のマークアップの例として

<textarea data-uk-htmleditor="{markdown:true}">...</textarea>

とあります。

上記のタグをJavaScriptが処理して、親の要素を付け加えてしまいます。
この様な処理が行われてしまうとReactでコンポーネントの制御が難しくなってしまうようです。
こよう様な「行儀の悪いコンポーネント」に対する対応方法もオライリー本に記述されていましたので、結果的にはなんとか取り込むことができそうでした。 (注:UIkitのコンポーネントに問題があるわけではなく、Reactのコンポーネントとしての管理を困難にしてしまう実装がされてるものに対し、「行儀が悪い」と表現しているだけです)

更に・・・

しかし、実際にReactコンポーネントとして利用できるように組み入れてみると、changeイベントを期待するタイミングで受け取れなかったり、Markdownとプレーン(単なるtextarea)とを切り替えるようにするため、編集内容の(プロパティ値)の同期や、編集内容をどう取得すべきかなど調べるのに苦労しました。
何度も利用するのを諦めかけましたが、試行錯誤の連続(というと大げさですが)の結果、少しずつ解決し、ある程度形にすることができました。

ベストな解ではないかもしれませんが、みなさんの参考になればと思いgistにコードを掲載しました。通常のReactコンポーネントとは違い、トリッキーなコード(オライリー本曰く)にせざるを得なかったので、なぜこのような書き方になるのかはReactのオライリー本を読んでみてください。