トップ «前の日記(2021-03-30) 最新 次の日記(2021-04-08)» 編集

日々の破片

Subscribe with livedoor Reader
著作一覧

2021-04-01

_ Rails6.1とReactJSの組み合わせは最強ではなかろうか?

Vueとか使ってないからわからんけど、とりあえず、Rails6.1で新規にアプリケーションを作れる状態になったので作り始めたわけだ。

で、プロジェクトを作ったら、app/assets/javascriptsのCoffeeがなくなっていてapp/javascript/packsとかができている。

面倒だなぁとWebpackerの仕組み調べたりyarnとか入れたりしながらいじくっていて、以前のアプリケーションからの持ち越しがあるので、CoffeeからES6に書き換えたりして、少なくともJSよりも1億倍Coffeeのほうがよい理由のラムダ式(というかfunctionとreturnを書かないで済む)はあるし、しかもreduceとmapが使えるからES6のほうが良いじゃんといじっているうちに、なんとなくReactJSで作りたくなってみたので、やってみた。

最初引っかかったのは、Bootstrapもついでにβ版だけど5にしたら、react-bootstrapというやつが4にしか対応していなくて(5と4でおれが一番引っかかったのは、pl-*とかmr-*とかが、ps-*とme-*に置き換わったことで、マイグレーションという概念のかけらも持たない愚かなことを、と思ったが、とはいえアラビア語みたいにlではなくそっちはeだみたいなやつのことを考えると、右左のような位置相対よりも始点終点みたいな文相対のほうが良いのかな(本当の理由は面倒だから調べていないけど)と納得したりしながら、まあ、たかだかトリガーでクラス名の切り替えする程度のことなら、onClick書けば済むからreact-bootstrapはリムーブして、生でBootstrap5βを使うことにした。

結果としてx-editableが使えないのはさすがに面倒だなぁと思ったが、Building inline editable UI in React: A complete guideというページが自分のeditableを作る方法を解説してくれていたので、ReactJSのコンポーネントの作り方の勉強がてら自作して(いずれにしても、コアコンポーネントだから自前のアプリケーション特化(ということは汎用と異なりコード量が圧倒的に少なくて済むからトラブったときの調査が超簡単)コンポーネントのほうが都合が良い)それも解決。

作る時に、onChangeを取ったりonKeyDownを取ったりしていろいろ試した(というかこちらが考えていない挙動に苦労した)おかげで、コントロールドとアンコントロールドの違いを内側から理解できたのも大きかった。

とはいえ、さすがにTinyMCEクラスの大物を独自に作るのはごめんだが、これもofficialなReactJS版が公開されていたのでOK。(考えてみれば、設計と実装の都合で、最初にインラインエディタの埋め込み、次にTinyMCEの埋め込みとなってしまったから、自作でインラインエディタを作る必要が出ていろいろ調べられたから良かったが、逆だったらちょっと話が違ったな)

ただ、本家のドキュメントでは、npmを使ったインストール方法しか出ていない。

既にyarnに寄せる(Gemfile.lockと同じようにyarn.lockで管理したいじゃん)ことを決めていたので、それは嫌だ。というわけでyarnのサイトでtinymceとreactで検索すると野良コンポーネントが山ほど出てくる。

困ったことに本家と同名のtinymce-reactでyarnを検索して最初に出てくるやつが、野良でAPIが全然違う。気づかずにyarn addして組み込んだら全然動かなくて(というかきょどりまくる)閉口して、しばらく試行錯誤してやっと本家版ではなく野良版だと気づいて、yarn removeして再度探してやっと見つけた(今は検索の2番目に出てくるが、最初に探したときは後ろのほうに埋もれていた)。

TinyMCEで編集させたやつをReactJSで利用するには、dangerouslySetInnerHTMLを使う必要があるのが不快極まるが、まあ、しょうがない。(同じく、受け入れるときにフィルタするGemが、サニタイズ言うなのrails-html-sanitizerなのも気に食わないがそもそもそれを言い出したらActiveRecordのsanitaize_sql_arrayを使えなくなってしまうので名前が気に食わないのはあきらめる)。

で、react-railsを入れると

<%= react_component('コンポーネント名', {コンポーネントのコンストラクタにpropsとして渡るオブジェクトをHashで記述} %>

と、Erbを1行書くだけでReactJSの世界に入れるのだった。

その結果、config/route.rbでいうところの''だけをhtml.erbにして、あとはすべてJSONを返すAPIにして、ReactJS側で全UIを処理できるからえらくきれいに書ける。

app/viewsにerbが1個除いて存在し無いからapp/helpersも空っぽで良い(view helperいらないし)。

JSONの返し方に、xml.builderを使う流儀もあるようだが、おれはシンプルにrender json: to_json持ちオブジェクトで済ませるのがすっきりしていて好きだから、本当にapp/viewsの下が軽い。

で、ReactJSの何が良いかと言えば、UIプログラミングに絶対的に必要となるライフサイクル管理が明確化されている点にあると思う。

オブジェクト生成時のconstructor(props)と、生成後のcomponentDidMount(componentWillMountはデプリケートされたようなのではなから考えない)、廃棄時のcomponentWillUnmountで、特にcomponentWillUnmountがあるおかげで、TinyMCEを作ったり破壊したりがえらく楽になった(tinymce-reactは勝手にcloseしてくれるので、生で使うときの廃棄管理が不要になっただけでえらくありがたい)。

あとは、とにかくAjax(大して使いやすいとは思わないが、みんなが使っているaxiosを使っている)でthenとかcatchしたらthis.setStateしてやれば勝手に表示できるのも良い点だと思う(this.setStateだけでオブザーバーパターン(コンポーネントで閉じているが、render関数をオブザーバー、それ以外のイベント受信系をオブザーバブル、stateをサブジェクトとみなした場合)が実現できているのでえらく楽)。

というわけで、今頃になってReactJSを使ってみているが、相当気に入っている。


2003|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|

ジェズイットを見習え