上記の「タグ」はBabelやTypeScriptやCoffeeScript(>=2.0)を通すと、機械的に以下のようになります。試したい方はBabelのREPLにいろいろ入れてみましょう。(reactのプリセットをONにするのだけは忘れずに)。ようなJavaScriptコードに変換されます3。この関数は実行されるとまさに上記のJSONに似たオブジェクトを出力し、それが仮想DOMの最終的な正体です。これだけなので、これを手書きしたい人はJSXを使わなくてもいいです(実際悟りを開いた開発者の中にはJSXが要らなくなる人もいるようです)が、本記事ではJSX使うべきということで通します。JSX記法さえあれば、古典的なテンプレートエンジンが頑張って実装してきたループ・条件分岐・子テンプレート呼び出し・テンプレート継承4・数値計算といった機能は、JavaScriptには全部元から備わっており、しかも超高速なのですから、使わない手はありません。普通にJSXをサポートしており、これらに馴染みがあれば導入のハードルは低いです。JSX自体は汎用性の高い単なるシンタックスシュガーですので、他の多くのライブラリでも採用されており、各種エディタでのサポートも非常に良好です。事実上の標準といっても過言ではない状態になっています。2015年ごろまではJSX構文周りのエコシステムが貧弱で、Reactの開発チームが専用のJSX変換ツールを配布したりしていました。その時の名残で「ReactはaltJSと相性が悪い」という記事がたまに残っています。慣れ親しんだテンプレートと比べるとループの可読性はわずかに落ちますが、タグの対応ミスなどのシンプルな構文エラーはコンパイル時にチェックされ、エスケープ漏れなどでXSS脆弱性が入る余地もほぼありません。TypeScriptを使えば厳密な型チェックも入ります。JSXは最初は違和感が強いでしょうが、実はこれは、XMLが今よりずっとメジャーだった時代に提案され、Firefoxに実装もされていたE4X記法とそっくりです。JSONがなかった昔、今のJSONの位置にXMLを使う未来が想像されていた時代があり、その時代には文字列リテラルを""で囲むのと同じ感覚で、XMLリテラルを<hoge></hoge>で囲んでJavaScriptで書くことは自然だと思われていたのです。それを知っていれば、JSXはJavaScriptのごく自然な拡張に見えてくるかも。このようにHTMLとJavaScriptが悪魔合体していることは、禁忌どころか、大事なメリットなのだと考えましょう。「HTMLとJavaScriptは分離せよ」は長い間の鋼の掟でしたが、それは、HTMLこそが単独でも成立する主役ドキュメントであり、サーバサイドでHTML内に実データを頑張って埋め込んでおり、JavaScriptがおまけだった時代の話です。action=...>と結びつかないフォーム要素」「見出し行だけのテーブル」「クリックしてもどこにも飛ばない<a>や<button>」等々、JavaScriptなしには意味を持たない“抜け殻”が静的に陳列されるだけの場と化していきます。CSSの表現力向上によってHTMLタグのレベルでデザインをごにょごにょする必要性は下がり続けています。撃ちまくることは、重要でも効率的でもないのです。機能的に関連するタグと動作を、名前付きでまとめて短く記述できるReactの記述方法こそが楽で合理的になります。使えばCSSすらも1ファイルにまとめて、完全に自己完結したコンポーネントが作れます。「JSXだと実装とデザインが分離できずデザイナーが辛いのでは」という点が気になる人がいるでしょうが、JSXでも規模に応じ、ビュー特化の(純粋にテンプレート的な)コンポーネントとロジックが絡むコンポーネントを分けられます。詳細はこれとかこれを参照してください。分けないほうが楽なことも多いので規模や設計次第です。「HTMLとJavaScript(とCSS)を1つにまとめてコンポーネントという単位で管理すべき」という思想自体は、React対抗としてよく名前が挙がるVueやRiotでも共通です。セマンティックなHTMLを失うことによるアクセシビリティ低下が気になる人はARIAを学びましょう。何らかの理由(ユーザ操作など)でページの状態が変わり画面を書き直す場合、ReactはゼロからDOMを毎回作り直すのではありません。画面を更新する際、Reactは新旧の設計図を見比べて差分を計算し、パッチ的にDOM操作を適用します。対応する操作に置き換えて実行します。これらを人間が手で書かなくても大丈夫。この差分描画はとても高速なため、ウェブページ全体をReact化して適用してしまうことが普通に可能です。1キーストロークごとに、アプリケーション丸ごとの状態が含まれたプレーンなJavaScriptオブジェクトでアプリケーション全体を「再描画」しても、割と快適に動作します(とても複雑なページだと最適化が必要)。これは文字列ベースのテンプレートでは遅すぎて到底できない芸当です。仮想DOMの比較はJavaScript内のみで完結する軽い演算なので、本物のDOM操作と比べると圧倒的に速いわけです。Reactを使えば、「状態を反映するようDOMをどう変更すべきか」を忘れてしまい、「ある状態に対応するDOMはどうあるべきか」の定義に集中できます。「ロード中はこのボタンとこのボタンを一時的に無効化してここにインジケータを表示して...」みたいな面倒なコードが一掃され、勝手にページ全体の一貫性が保たれます。さっきのjQueryの例も、あれだけだったら別に大したことなかったですが、ユーザ操作に応じて在庫有無やユーザ評価やカラバリ選択ボックスやポップアップメニューを動的に付与したり、同じ商品やボタンを2カ所に表示しつつ同期したり、商品をフィルタリングしたりソートしたり...といった様々な動きをつけていくと混沌の扉が開きはじめます。サンプルレベルではReactの威力は実感しづらいのですが、実用的なアプリではバグの心配が激減します。ページ全体の情報を1箇所に集められるので、「ブラウザをリロードされても状態を復元する」「ユーザ操作を元に戻す/やり直す」といったことの実装も比較的容易です。超軽量なコンポーネントReactでは「部品」「独自タグ」的なものがアホみたいに簡単に書けます。それを組み合わせるのも非常に簡単です。コンポーネントの定義といっても何しろ単なる関数ですから、ワンライナーでもよい。コンポーネントの利用の際も、標準のHTML要素と独自タグの境界はほとんどなく、まるでHTMLに突然フル機能のカレンダー「タグ」や掲示板「タグ」が実装されたかのような感覚で扱えます。/>;これは極端にシンプルな例ではありますが、実際にアプリケーションを作るにあたって、コンポーネントはできるだけ単純な関数で書き、それを組み合わせてアプリにしていきます。数行で済む「ヘッダーコンポーネント」「目次コンポーネント」とかを何十個も書いて、最終的に1個のアプリを作り上げていくイメージ。UIとかのコンポーネントには真似できません。SubversionのブランチがGitのブランチに変わったくらいのインパクトがあります。こんな芸当が可能であるために、「コンポーネントが原則として内部状態を持たない(ステートレス)」ことがとても重要です。原則的にステートレスなコンポーネントコンポーネントがステートレスである、とは、返すDOMの設計図が、外部から「タグの属性」(props)として与えられた情報のみで一意に決まるということです(数学的な意味での関数に近い)5。この思想のお陰で、コンポーネントは単なる関数で書くことができます。Reactを使うにあたって、jQueryから一番考え方を変えないといけないのがこの部分でしょう。jQueryのコンポーネント(カレンダーでも、スライダーでも)は内部状態(プロパティ/ステート)として「現在の入力値」とか「disabledかどうか」とかを持っているのが当たり前でしたし、それの初期化と出し入れで記述が長くなる傾向にありました。Reactのコンポーネントでは、大事な状態は外部から流し込まれます。コンポーネントとは外部からの情報をDOM設計図に変換するプリズムに過ぎません。心得て、可能な限りそのように作るべきです。...と書きましたが、必要に応じてステート付きのコンポーネントも書けます。以下の2通りの方法があります。関数コンポーネント内でフックを使う。16.8から利用できる新機能)ES6のクラス構文を使う。新しいAPIだけあって前者の方が遙かに楽なので新規コードでは基本的にそちらをお勧めしますが、当面はクラスで書かれたコンポーネントを扱うことも多いと思います。ステートにするのは「親コンポーネントと一切やりとりする必要がないプライベートな内部状態」だけにしましょう。「ドロップダウンメニューが今ドロップダウンされているかどうか」とか。「外部に状態がある」というのはカスタムコンポーネントだけの話ではありません。標準フォーム要素ですらその発想が徹底しており、ステートレスな振る舞いをするようになっています。要素はリードオンリーになり、中身を変更できません。CodePen.編集可能にしたければどうするのかというと、例の「ページ状態を管理しているプレーンなJavaScriptオブジェクト」を経由します。テキストボックス内で入力操作が起きた場合、内部状態が変わってからイベントが発火して外部状態を更新するのではなく、コールバック関数経由で外部状態を先に変更してから画面を「再描画」するのです。外部の1カ所だけにあり、DOMはそれを反映しているだけ、というこの構造は、複雑なフォーム・アプリほど楽さが際立ちます。駆使して、「生データの状態をDOMに反映させる」のと、逆の「DOMの状態から生データを再構築する」のを両方を書くことになりますが、この構造ならそういう作業は要りません。いう標語を聞いたことがある人は、それが指しているのはこれのことです。属性が華麗に復活しているのを見て驚いた人がいるかもしれませんが、Reactの設計思想的には何も問題ありませんので、こういう新しい記法だと思いましょう。内部ではちゃんといろいろ最適化されているそうです。UIの半分の行数と1/5の時間で実装できる感じ(6個のステートレスコンポーネントの組み合わせ。他にも便利なUIライブラリがたくさんあります)。React自体は単機能の描画ライブラリであり、「外部の状態」をどこにどうやってどんな粒度で保存すべきかについて一切関知しません。小さなアプリなら上記サンプルコードに毛が生えた程度のものでページ全体をまるっと更新するので何の問題もありません。規模が大きくなってきた場合は、この「外部の状態」を管理するための別ライブラリを混ぜて使う人が多いです。FluxがどうとかStoreがどうってやつです。過去には(厳密にはReact外の話とはいえ)この部分が混沌としていましたが、今はとりあえずreduxという軽量なライブラリが最も人気です。深く考えたくない人はとりあえずこれを使っておけばいいんじゃないでしょうか。誤解されていますが、reduxのようなものは必須ではありません。Reactのチュートリアルなどでも使われていません。小さなアプリでreduxのような専用の状態管理ツールをいきなり導入してもタイプ量が増えるばかりで実用上のメリットがよく分からないと感じると思います。ユニットテストや依存性注入などの概念が骨身に染みついた上で大規模開発をする人以外は、まずreduxなしでReactの考え方に慣れることをお勧めします。Reactが向かない場合もちろんReactが常に万能なわけではありません(タイトルが釣りっぽいのはごめんなさい)。Reactの弱点、Reactが向かない場合もありますのでよく考えて使いましょう。React自体の理解に加えて、Babel/TypeScriptのようなトランスパイラの知識は(絶対ではないけど)ほぼ必須で、Webpack/Browserifyのようなモジュールバンドルシステムの知識も(絶対ではないけど)ほぼ必須。そこまで至っていない人にとっては多少学習コストはあります。Webpack等の勉強をしたくない場合はReact公式のスターターを使えば5分でReactアプリが作れますが、まあ内部で何をやっているのかは知っておいた方が良いでしょう。複雑で動的なアプリほど向いているけど、HTMLが主役で動的な要素が少ないサイトや1日でコーディングが終わるようなサイトは、jQueryで特に困りません。大雑把ですが、作ろうとしているものが「記事(HTMLが9でJavaScriptが1)」なのか「アプリ(HTMLが1でJavaScriptが9)」なのかで分けるという指針でいいと思います。Reactが向いているのは後者。普段の仕事内容によって「もう一生jQuery要らない」って人もいれば「一生jQueryしか要らない」って人もいていいと思います。JavaScriptベースのライブラリなので、デザイナ系の人の理解と協力が必要(とはいえそんなに難しくないはずであることは前述しました)。場合はサーバ側の協力も必要(基本的にはサーバ側は楽になりますが)。純なReactアプリではHTMLは数行くらいの固定ファイルになり、あらゆる実データはJSONのAPI経由などで来ます。サーバサイドに必要なのはAPIであって、テンプレートでHTMLにデータを埋め込むことではありません。React最新版ではIE8以下は切り捨て。いいよね...ちゃんと最適化したjQueryよりは若干遅いので、本当にパフォーマンスが必要なゲームなどでは要検討。「ちゃんと最適化した」jQueryとの比較ですよ?ReactにとってDOMとはあくまで外部状態を反映する映像に過ぎないので、逆にDOMからデータを取ってくるような作業(スクレイピング)は行えません。jQueryという記事が話題になっていましたが、はてブとかの反応を見る限り、「むしろjQueryの使いやすさが良く分かった」という人が予想外に多い感じでした。その記事の冒頭部分には「DOMを直接操作することはアンチパターンとなりました」とあり、記事はその前提で書かれています。「(頑張れば標準APIでもjQueryと同じことを書けるから)もうjQueryは必要ない」ではなく、もっと根本的に「(jQuery的なDOM操作なんか人間がやることじゃないから)もうjQueryは必要ない」です。jQueryを使うことで標準APIより数文字節約できるような作業の大部分は、そもそも1行も書かなくてよくなったのです。「昔は便利だった」jQueryのユーティリティメソッドも、今はほぼ標準で代替可能です。系くらいですが、そのくらいならもっとコンパクトな代替品があります。気づいてしまい、残ったjQuery依存を消し去りたいという衝動に駆られたら、はじめて、ああいう記事の出番なわけです。数カ所の数文字のタイプ数増加で、100KB超のライブラリを捨て去れるなら、Webでのメリットは大きいです。jQueryというサイトがまとまっていてお勧め。お陰様でよく読まれる記事になっていますので、ブクマコメント等を元に定期的に加筆修正やアップデートを行っています。最後の更新は2019年2月です。いま見当違いのように見えるコメントは、大抵は私が加筆したせいです。ちなみにAngularもバージョン2からは後ろにJSが付かないのが正式名称です。「仮想DOM」は、ドキュメントなどでは「React要素」と呼ばれています。これはReactの応用先が今やブラウザ上のDOMのみに限られないからです。この記事では有名かつ直感的な名称である「仮想DOM」を使用します。Props」とか「高階コンポーネント」という手法を勧めています。詳細は他の記事に譲ります。厳密には「ピュアレンダ」と「ステートレス」とは別の概念として区別する必要がありますが、この記事では割愛します。