この連載記事は、React を学びたい JavaScript 開発者のための入門コンテンツです。対象とする React のバージョンは執筆時点で最新の v16.13 系です。連載記事は以下の通り。
Reactとは何か
JSX
属性と状態
フォームとイベントハンドリング
ToDoアプリを作ってみよう
副作用
カスタムフック
Reactプロジェクトを始める方法
本章ではまず、React とは何のための、どのような特徴を持ったライブラリなのか、について説明します。実際のコードが出てくるのは次章以降なので、抽象的に感じられる箇所もあると思います。後続の章で React の機能を知ると、よりよく理解できるはずなので、とりあえずそのつもりで読み進めてください。
React とは
React は、自称「ユーザインターフェース構築のための JavaScript ライブラリ」です。少し抽象的なので Web の文脈で一言で表現すると、DOM 操作ライブラリです。
React が利用される場面は Web に限りません。実際、React Native は React によるモバイルアプリ開発を実現して(少なくとも目指して)います。ただ、この連載では Web 開発における利用を想定して話を進めます。以降の説明もすべてその前提で読んでください。
周辺のエコシステムの充実によって、大規模なシングルページアプリケーションを開発できる表現力を発揮していますが、あくまで DOM の操作が本来の機能です。
「React は、DOM 操作の異なるアプローチ」「今まで素の JavaScript や jQuery などで手動で行っていた DOM 操作を、効率化させてくれるライブラリ」と理解しておいてください。
素の JavaScript や jQuery でももちろん DOM 操作はできます。しかし React は、DOM 操作を効率的に行うしくみを内部に持っています。
React が備える DOM 操作の特徴は、以下の2点が挙げられます。
- 仮想 DOM(Virtual DOM)
- データと UI の同期
そして、React の構文は、コンポーネント指向の開発スタイルを可能にします。これは処理的な無駄のなさやパフォーマンスというより、論理的な設計面で意義のある点でしょう。
React を使うと、「コンポーネント」がコードをまとめる単位になります。設計指標、つまりコードを整理する基準の存在は、本格的なアプリケーションを構築するうえで重要です。
ここから、それぞれのキーワードについて、もう少し掘り下げて説明します。
仮想 DOM
React は、仮想 DOM(Virtual DOM)という JavaScript オブジェクトを内部に持っていて、DOM 操作を効率化するために使っています。
下図は、素の JavaScript で DOM 操作を行うイメージ図です。開発者は、JavaScript の API を用いて、DOM を具体的にどのように更新するかをコーディングします。
単に JavaScript の便利なラッパーである jQuery を用いても当然同様です。
これに対して、下図は React を使った場合の DOM 操作イメージです。React は、DOM 構造を JavaScript オブジェクトで表現したコピーを内蔵しています。それが Virtual DOM です。
開発者は、具体的な DOM 操作指示はコーディングしません。(後述するように)React 内のデータを更新して、あとの処理は React に任せます。
React は、データの更新を検知して、そのデータ更新によって、結果として DOM がどのように変わるべきかを計算します。つまり、実際に DOM を変更してしまう前に、JavaScript 内の仮想 DOM で変更後の DOM の状態をエミュレートします。そのうえで変更前の状態も残しておいて、両者の差分を計算して、必要なだけ、無駄のない DOM 操作処理を行います。
この仕組みが、大抵の開発者が自力で書くよりも効率的な DOM 操作を実現します。
仮想 DOM での計算処理が増えているぶん効率が悪そうですが、性質上、DOM を更新する処理よりも、メモリ上で実行される JavaScipt の計算処理のほうが軽量なので、そのぶんを差し引いてもパフォーマンス的に有効と考えられるらしいです。
誤解してはいけないのは、仮想 DOM はブラウザが提供する新しい DOM 操作 API などではない、という点です。あくまで JavaScript レベルの賢いコーディング手法です。
まれに、「jQuery は直接 DOM を触るから遅い」と聞きますが、これは結構文脈を省略した乱暴な言い方だと思います。そもそもブラウザは、DOM 操作をするのに「直接 DOM を触る」以外の方法を用意していません。「React を使ったほうが、最適化の仕組みが備わっているぶん、複雑なアプリであるほど、速度的なアドバンテージが期待できる」というくらいが、よりフェアな表現ではないでしょうか。
ライブラリの背後で動いている仕組みなので、普段開発者として意識することはないと思いますが、 React の特徴の一つとして知っておきましょう。ちなみに 仮想 DOM の仕組みは、React 以外に Vue.js など他のフレームワークでも採用されています。
データと UI の同期
この項は「属性と状態」の章までを読んだあとで、よりよく理解できるでしょう。
次は、React を用いた開発でのコードの書き方に関係あるお話です。上で触れたように、React では直接的な DOM 操作をコーディングしません。props(属性)や state(状態)といった React が管理するデータを更新することで、あとは React が処理してくれます。
これがプログラミングスタイルとしてどのような利点があるのか、まずは普通の JavaScript プログラミングについて考えてみましょう。
大抵の場合の JavaScript の役割は、「イベントを検知して」「なにかのロジックを実行して」その結果「DOM を更新する」ことですね。下図はその例を表しています。
素朴に書くと、DOM 更新コードとそれ以外のロジックが渾然一体となりがちです。ビジネスロジックと innerHTML
や createElement
的な処理(jQuery だと .html()
とか)が交互に出てきて、結局どういう DOM が作られるのか判然としないコードに出くわした、というか書いたことありませんか?(私はあります。)
React では DOM 更新をライブラリが隠蔽しているので、データ更新処理などのビジネスロジックを DOM 更新と切り離して記述することができます。
この辺の説明は、実例がないとなかなか意味が分かりにくいと思います。「属性と状態」を読んでから、また戻ってきてください。
コンポーネント指向
この項は JSX についての章を読んだあとで、よりよく理解できるでしょう。
React では、UI(見た目)と、それが扱うデータをまとめた「コンポーネント」を作成し、組み合わせていくスタイルで開発を進めます(*1)。
コンポーネントとは、「部品」という意味です。Web フロントエンドの文脈で言うと、ページを構成する UI 要素を、独立して再利用可能な単位に切り出したプログラムです。たとえば、ボタン、カード、タブ、アラートメッセージ、テキスト入力欄、タグ、バッジ…などなど。
それらの UI 部品を、React コンポーネントとして定義します。React コンポーネントは、JSX の構文により、あたかもオリジナルの HTML 要素であるかのように記述できます。
<Card>
<CardHeader>
<Avatar userName="john" icon="/images/avatar/john.png" />
<Title>...</Title>
</CardHeader>
<CardContent>
...
</CardContent>
<CardAction>
<Button type="default">...</Button>
<Button type="primary">...</Button>
</CardAction>
</Card>
UI とデータ、機能がまとめられたコンポーネントというコンセプトは、既存の HTML 要素を模していると言えます。なぜなら HTML 要素自体が、そのような性質を持つからです。
<a>
要素を考えてみてください。<a>
要素は下線つきのブルーの文字という、独特の UI を持っています。そして、どこに遷移すべきか、というデータ(href
属性)と、その URL に GET リクエストを送信する、という機能を持っています。
そして、「部品」という言葉から想像される通り、再利用性にも優れた手法です。ここでも既存の HTML 要素がいかに再利用性に優れているか考えてみましょう。
React コンポーネントも、まさにそのように設計され、作られます。コンポーネント指向は、HTML を自然に拡張する開発スタイルです。
連載
-
データと振る舞いをまとめたクラスを組み合わせていく Java のようなサーバサイド言語の開発と似ていますが、React の場合は抽象化の単位がユーザーインターフェースになります。
↩