reactRパッケージでRからReactを実行する
このエントリは R Advent Calendar 2017 20日目の記事です。
こんにちは。
最近Shinyでちょっと複雑なことをやりたくてJavaScriptを書いていたのですが、
どうせなら最近よく書いている React を使いたいなと思っていたところ、
reactR というドンピシャなパッケージを見つけたので紹介します。
なぜReactなのか
React は Facebook製のUIを構築するためのJavaScriptライブラリです。 シングルページアプリケーションを作るときなどによく採用され、近年人気を博しています。 詳しい解説はネット上にいくらでもあるので省略します。
少し複雑なことをやろうとするとjQueryはすぐに読みにくくなってしまいますが、Reactならば直感的に書けます。 また、React用に用意されているリッチなコンポーネントライブラリも増えてきており、例えばこれをShinyで使えれば、既存の用意されているもの以外にも使えるデザインの幅が広がります。
というわけで reactR をご紹介します。
ただ、このパッケージはまだ開発が十分でないことをご留意ください。
reactRの作者について
reactRパッケージの作者は、@timelyportfolio さんです。 この方は可視化や地理空間情報分析に長けており、RとJavaScriptのプロフェッショナルという貴重なスキルセットをお持ちな方です。
以前紹介した「mapedit」「mapview」もこの方が開発に関わっており、個人的に目が離せない人物です。
簡単な使い方
では、使ってみましょう。
library(reactR)
library(htmltools)
x <- tagList(
reactR::html_dependency_react(),
tags$div(id = "example"),
tags$script(
HTML(
reactR::babel_transform("
const Hello = <h1>Hello, ReactR!</h1>
ReactDOM.render(
Hello,
document.getElementById('example')
)
")
)
)
)
browsable(x)

上記を実行すると、図のように「Hello, ReactR!」と表示されます。
簡単に言えば、tag を駆使してHTMLの骨格を作り、reactRの関数でreactを読み込んだりreactで書かれたJavaScriptコードを挿入しています。
reactRが提供する関数はたった2つです。
html_dependency_react
reactの htmltools::htmlDependency を作ってくれる関数です。
これにより、外部ライブラリであるreactをcdnを用いて読み込むことができます。
さきほどのコードを実行してできた画面のソースをみると、しっかりreactが <script> タグに挿入されています。
babel_transform
babelを用いてコードを変換してくれる関数です。 これにより、ES2015やJSXを用いてコードを書くことができます。 特にJSXは、Reactを書くときに欠かせないのでありがたいですね。
ちなみに、この関数の内部では V8 パッケージが使われています。 V8パッケージは、Google製のJavaScript実行エンジンをRから呼び出すパッケージです。
日本語の記事だと yamano357さんが既に活用していますね 。さすがです。
サンプル
reactRのレポジトリにはいくつかサンプルがあります。
それを読むと、html_dependency_react の内部を参考にhtmlDependencyを定義すれば、外部パッケージを読み込めるようです。
ということは、冒頭に書いたように、React用に提供されているライブラリも使うことが可能です。
例えば、MicroSoftが提供しているReact用UIライブラリ「office-ui-fabric-react」を使ってみると、
library(htmltools)
library(reactR)
fabric <- htmlDependency(
name = "office-fabric-ui-react",
version = "5.23.0",
src = c(href="https://unpkg.com/office-ui-fabric-react/dist"),
script = "office-ui-fabric-react.js",
stylesheet = "css/fabric.min.css"
)
browsable(
tagList(
html_dependency_react(),
fabric,
tags$div(id = "app-button"),
tags$script(HTML(babel_transform(
'
const btn =
<Fabric.DatePicker placeholder="Select a date..." />
ReactDOM.render(btn, document.querySelector("#app-button"));
'
)))
)
)

このような感じで、ライブラリが提供しているDatePickerが使えるようになりました。
まとめ
サンプル少なすぎてすみません。 本当はもっとリッチなものをつくりたかったのですが、 いくつかエラーにハマり、載せるクオリティのものが作れないまま時間切れとなりました。 なにか作ったら追記しますが、その前に解決すべきエラーが多そうです。 この分野は少しマニアックではありますが、 なかなか面白いので、もう少し深堀を続けるつもりです。
使いこなせるようになったら自作Shinyアプリに載せたいですね。
そうそう、reactと同じくらい人気のフレームワークである「vue.js」が使えるRパッケージ、「vueR」もあるそうですよ。残念ながら僕はvueを書かないので使う見込みはなさそうですが、vue派の人はぜひどうぞ。
エンジョイ。