みなさんReactやってますか。やってますよね。最近React Native流行ってるし。
んでいきなりなんですが、あのReactとかいうやつ、実は 特にウェブとは関係ないライブラリ なんですよね。ええぇ……。なのでこの記事ではそれについてだらだらと説明したいと思います。
この記事の背景
最近のReact Nativeブームで「React is 何」「React Nativeについて3行で教えてくれ」みたいなアレコレがよく発生するんですが、その際に「Reactはウェブ向けライブラリである」という先入観がだいぶ素直な理解を阻害しているなーと感じました。
「Reactはウェブ向け」って登場初期は全然間違ってなかったんですけど、厳密には2015年には全く違う状況になって、2019年とか2020年になると完全に間違ってると言える状況が発生し出したので、改めて説明させていただこうと思いました。
別に知識が間違ってるとか間違ってないとかは正直どうでもいいし、本当にそんな細かいこと気にするなら2016年にはキレてたと思います。ただ、去年ごろから意外と実害が出始めてきてるので、ちょっと軌道修正試みたいと思っただけです。具体的には僕の解説負担が爆発的に増加してるって感じですね。キレそう。
だいたいReact Nativeがわるい。
読みたくないから短くまとめろ
メタい流れ
- React NativeやるならReactについて知っとくと理解がスムーズになる
- 同じ質問何回もさばくのしんどいしキレそうだった
- それなら記事にまとめた方がいいよね〜〜〜〜
内容
- Reactはウェブ向けライブラリとして登場した
- なんかReact Nativeとかいうのも出てきた
- React NativeとうまくやるためにReact自体は2015年にウェブから完全に独立した
- ウェブ向け機能はreact-domってライブラリがやるようになった
- Reactに残った機能はコンポーネントのツリー管理とか差分検出システムぐらい
- ウェブとかHTMLに依存してないからなんでも作れるようになった
Reactの歴史とウェブとの関係 - 前半戦
「ReactはウェブUI(View)のみを担当するライブラリである」
よく使われる説明です。Reactは2013年にウェブUIのために誕生したJavaScriptライブラリです。Facebook製です。細かい説明は他の記事に任せますけど、ウェブ開発が抱えていた多くの問題を一度に解決しました。やったぜ。
それで紆余曲折あって、まあ経緯は知らないんですけど、2015年にReact Nativeというものが生まれました。React NativeはJS実行エンジンとReactぶち込んで、JSの処理をネイティブ側にブリッジしてネイティブアプリ作れるぜというやつです。細かいことはググってください。今年(2020年)あたりに細かい内部アーキテクチャ変わりそうな気配もあるんでキャッチアップ忘れずに。
これが2015年前半までの出来事。なんかネットではこのあたりで情報がせき止められてて、2020年の今になって僕のところに説明負担の増加という被害がやってくる。ちくしょう!
Reactの歴史とウェブとの関係 - 後半戦
こっから2015年後半からの話。
React Nativeでは、というか「ウェブ技術でネイティブを」系のアレでだいたい発生するんですが、コードベース共有できない部分が出てきます。HTMLとかDOMとか一切使えない。あくまで「ウェブ技術の流用」であって「ウェブコードの流用」ではないので。パフォーマンス捨ててるWebView系のやつは例外。
じゃあReactがウェブ周りのコード持ってるの無駄じゃん、ってFacebookが気づいたらしく、2015年後半には Reactからウェブ周りのコードが消滅 しました。ウェブ周りのやつはreact-domっていう新しいライブラリ作ってそっちに全部移動。なかなか大胆なことをしはるね。
このあたりで「Reactはウェブ向け」ってのは厳密には違うようになったんですが、実際はReact+react-domの利用が一般的だったし、React Nativeなんて使うのよっぽどの物好きか最先端イケイケ企業しかいなかったんですよね。なんでまあ、ウェブライブラリとして認識してても実害が一切なかったんですよね。
じゃあReactって何やってるんだよ
ウェブ向けの機能消滅したんでしょ。じゃあReactって何やってんの。
React自体も細かくモジュール別れてるんでめんどくさい話をすると非常にめんどくさくなるんですけど、だいたいreact(core)+react-reconcilerが使われてるはずなのでここの話だけします。
Reactコアの機能は以下の通りです。
- コンポーネントの定義
死ぬほどしょぼい。
react-reconcilerの機能は以下の通りです。
- コンポーネントのツリー構造をなんかめっちゃうまいこと管理する
- 差分検出とかする
こっちがみんなの想像する本体っぽい。中身はほとんどFiberが占めてる。
という感じで、雑にまとめると「Reactがやってるのはコンポーネントツリーの上手な管理と差分検出だけ」になります。
Reactのレンダラ
Reactがソロバンだけ担当して特に現場に降りてこない調子乗ったやつってのはわかりました。
じゃあ現場はどうなってるの、っていう話になると、ここでやっとreact-domとかreact-nativeが登場します。react-domはReactが弾き出してくれた結果をDOMに転写するし、react-nativeはReactが弾き出した結果をネイティブアプリに転写します。あとはそれぞれで使うコンポーネントが含まれていたり。
この辺のライブラリのことを「レンダラ」って呼んでます。日本語に直すと「描画マン」です。描画します。馬車馬のように働け。
レンダラが描画する対象は本当になんでも良くて、CLIにレンダリングするInkなんてのもあるし、IaCやろうとするバk…天才的なAdaptっていうのもあります。まあここは本当になんでもよいです。
こうやって描画の仕組みを完全にReact本体から切り離すことで、Reactはウェブ界から解脱したなんか概念的なものになりました。
よくわからん説明負担がマッハ
まあこんな細かい話はぶっちゃけどうでもいいし、そんなこと知らなくても人間は一生食っていけるわけですよ。技術的に正しいかと人生的に正しいかは別。こんな重箱の隅突くような記事書いてる暇があったらコード書け。
でも時代によっていろんな事情があって、ここ数年でReact Native流行ってきましたよね。Airbnbは犠牲になったのだ。犠牲の犠牲、その犠牲にな。そうなってくるといろんな人に説明求められるようになります。「React Nativeってどうなん」って。
ウェブ政治的な話には答えられないけど技術的な答えならできるよってことでいろいろ話すんですけど、だいたい毎回同じ話をします。そもそもReactってHTML関係ないよとか、レンダリングターゲットは自由に付け替えられるよ、とか。だからWebViewとかと違ってどうのこうのみたいな話。ええそうです。この記事に書いてる内容です。
最初の5人ぐらいにはちゃんと説明するけど、これが累計20人とか30人になってくるとだんだん説明が雑になってくるしめんどくさい。そもそも「興味ある人」ぐらいじゃ詳しくググらんし、しゃーないかって思ってました。
そして最近になって気付きました。この辺の話、ググっても出てこねえ。そりゃみんな知らんわってなる。なので書きました。存在しないものに文句言っても仕方ないので自分で用意する方が建設的。
さいごに
べつに技術を正しく知る必要はないんですけど、さすがに毎回同じ説明を何回もするの面倒なんでURLだけズバーンと投げれば終わるようにしときたかったので書きました。がんばった。
んじゃあこれからもReact頑張っていきましょう。アディオス、アミーゴ!