これから始めるReact.js 第1回 React.jsとは

Facebook社が開発しているライブラリ、React.jsを開発に取り入れてみようと思っているReact.js初学者向けのシリーズです。第1回目はReact.jsの特徴について、既存のライブラリとの相違にも着目しながら解説します。

発行

著者 杉浦 有右嗣 シニアエンジニア
これから始めるReact.js シリーズの記事一覧

本シリーズ内で紹介している内容は利用できますが、現在のバージョンでは新しい書式などが追加されているので注意してください。(2020年7月現在)

はじめに

このシリーズでは、昨年より徐々に注目を集めているReact.jsについて解説していきます。そもそもどういったものなのか、既存のフレームワークとの違いはあるのか、どうやって使うのかまで、広くカバーしていく予定です。

最初に、読者が気になっているであろう用語や疑問についてまとめて説明しておきます。先にこれらの前提知識を押さえておくと、React.jsの理解にも役に立つでしょう。

React.jsとは

Facebookが開発、OSSとして公開しているライブラリです。GitHubリポジトリはfacebook/reactです。

特徴として、次の3点が挙げられています。

  • Just the UI:MVCのVにあたるUIのみを構築するためのもので、他にどういったライブラリと組み合わせるかは問わない
  • Virtual DOM:実際のDOMに対する操作を抽象化し、シンプルなコードでそれなりのパフォーマンスを提供する
  • Data flow:一方向のデータフローにより、従来の双方向データバインディングを実現するコードよりも簡素でわかりやすい

上記の特徴をひとまず頭に留めておいてください。

記事執筆時点(2016年3月)での最新バージョンはv0.14.7ですが、初のメジャーバージョンであるv15.0.0-rc.1が、3月頭にリリースされていることからも、十分にproduction readyなライブラリであることがうかがえます*。

*注:初のメジャーバージョンが、なぜv15.0.0?

v0.系から、いきなりv15のリリースというのはあまり聞かない話ですが、公式ブログでは、誰もが抱きそうな疑問「What Happened to 1.0.0?」という見出しで、もしメジャーバージョンのナンバーがAPIの安定性を示し、製品として使いうるという信頼を呼び起こすものなら、我々はずいぶん前にそこにたどり着いていると述べています。つまり、そのようなバージョニングに従うのであれば、v15に値する、安定性と信頼性はあるという意味でしょう。

React.jsをめぐるさまざまな用語

React.jsについて調べようとすると、頻出する用語があると思います。まずは、それらの用語について簡単に触れておきましょう。

ライブラリ? フレームワーク?

Webアプリケーションに関する用語で混同されがちなこれらですが、React.jsはライブラリです。

フレームワークは、アプリケーションに必要な処理の流れを規定するもので、いわゆる設計を手助けしてくれるものです。一方、ライブラリはただの関数の集合体と言ってしまってもよく、処理の流れや設計には特に関係ありません。

みなさんがよくご存知な技術で考えると、jQueryはライブラリ、AngularJSはフレームワークと言えばわかりやすいでしょうか? ただ、どちらにせよ、この区別はそこまで重要ではないので、あまりとらわれ過ぎないようにしたほうが良いでしょう。

React.jsは、UI構築のためのライブラリと覚えておいてください。

AngularJS、Vue.js、Backbone.jsとの違い

React.js以外にも、AngularJS、Vue.js、Backbone.jsなどWebアプリケーションの構築に用いられる技術*があります。

*注:AngularJS、Vue.js、Backbone.js

AngularJS、Vue.js、Backbone.jsに関しては、次のシリーズなども参考にしてください。なお、実際の実装については情報が古くなっている部分もあります。

React.jsは、あくまでUIを構築するためのライブラリであるという点で、フレームワークであるAngularJSとは趣向が異なります。

またVue.jsやBackbone.jsのBackbone.Viewとは、次節で説明するVirtual DOMのアプローチをしている点で一線を画しています。

コードの書き味という意味ではあまり大差がないと感じるかもしれませんが、その裏で行われていることには、大きな違いがあります。

React.jsが現在の類似技術のどのあたりに位置するものか、大まかに掴んでもらったところで、さらにReact.js特有の概念の説明をします。

Virtual DOMとは

冒頭でReact.jsの特徴として紹介したうちのひとつにもありました。

Virtual DOM(バーチャル・ドム)とは、日本語にすると「仮想DOM」、対義語は「実際のDOM」と言ったところでしょうか。ここで言う実際のDOMとは、ブラウザで実際に表示されているDOM構造のことを指します。

ブラウザで現在表示されているHTMLのツリー構造(=実際のDOM)に対して直接処理を行い、その表示を更新するというのが今までのアプローチだったとすると、Virtual DOMを採用した場合のアプローチは少々異なります。

Virtual DOMのアプローチでは、実際のDOMと対となる構造体(=仮想DOM)を用意し、その構造体に対して処理を行います。そして、その結果生まれた差分だけが実際のDOMに反映します。

この構造体と、差分適用のアルゴリズムを合わせたものをVirtual DOMの実装と呼びます。React.jsの他にも、Virtual DOMを採用しているライブラリとして、dekuなどがあります。

この構造体は、ただのJavaScriptのオブジェクトであり、このオブジェクトの状態と表示されている画面(=実際のDOM)は必ず一致します。結果、このオブジェクトだけを気にかければ良くなるため、設計コストが下がるというのがVirtual DOMの利点です。

また、この構造体の状態を反映する先が、ブラウザの実際のDOMである必然性もありません。そのため、たとえばネイティブアプリ向けのreact-nativeであったり、three.js向けのreact-three-rendererといったものも存在します。

このVirtual DOMの実装と、それを使ったコンポーネントを記述するためのヘルパー関数などをまとめたものがReact.jsということになります。

どんな用途に向いているのか

さて、このVirtual DOMを用いたReact.jsですが、どういった用途に採用すべきなのでしょうか。

ただのUIライブラリであるため、基本的にはどんな規模のどんな用途であっても利用することは可能です。筆者としては、採用基準として見るべきポイントは大きく2つあると思っています。

速度を求めるか?

1つは速度を求める場面かどうかです。Virtual DOMという実装上、データの更新による差分が発生した際、どの部分を変更するのかを調べるという工程が必ず発生します。

モダンブラウザ環境においては、この差分を検出し必要な部分だけを更新するというアルゴリズムは十分に速く、おそらく大概のケースでは、パフォーマンスは問題にならないと思います。

ただ一部の環境(レガシーな環境であったりモバイル端末など)においては、この工程すら省いて速度に特化したいというケースがあるかもしれません。その場合はReact.jsを使わずに、必要な部分のみを更新するようにしたほうがよいでしょう。

既存のアプリケーションとの親和性はあるか?

もう1つのポイントですが、既存のアプリケーションとの親和性があるかです。先ほどVirtual DOMの正体はただの構造体であり、実際のDOMには触れる必要がないと説明しました。

しかし逆に、実際のDOMに対する処理を行うことの多いjQueryのプラグインのようなものが多々使われているようなアプリケーションだと、どうでしょうか。

Virtual DOMが表す構造体の状態と、実際のDOMの状態が一致しないとなると、Virtual DOMを用いることによるメリットを享受できないことになります。

そしておそらく、それらのプラグインをすべてVirtual DOMのアプローチに則ったコンポーネントとして再構築するのは非常に骨が折れる仕事になると思います。ですから、こういったケースにReact.jsを投入するかどうかは、慎重な判断が必要だと思います。

Fluxとは

React.jsと併せて語られることの多い単語だと思うので、軽く解説しておきます。Flux(フラックス)は、特定のライブラリやフレームワークを指すものではありません。

これはMVCと同じく「設計思想・デザインパターン」のひとつで、React.jsのようなライブラリと特に親和性の高いものです。また、ただの考え方であるため、React.jsを使う場合は必ずFluxを採用する必要があるというわけでもありません。

前述のとおりReact.jsの役割は、単一の状態を表す構造体を、ただ表示することでした。となると、この構造体であるJavaScriptのオブジェクトを、いかにして管理・更新していくかが設計の最大の焦点となります。

Fluxの考え方のもっとも特徴的な部分は、「データの流れを一方向にすること」です。各コンポーネントが表示すべきデータを、各コンポーネントが個別に更新するのではなく、アプリケーションとして単一のデータフローを形成し、いかなる場合も、その流れに載せるようにします。

そうすることで、各コンポーネントの責務は受け取ったデータを表示するだけとなり、データを変更するロジックとの関心を分離することができます。

React.jsについてよく知らないうちは、Fluxの利点や意義を完全に理解することはできないため、今回はこれ以上の説明をしません。ただFluxの思想を取り入れたコード、具体的なライブラリとの組合せの例なども、このシリーズで追って取り上げる予定です。

開発環境について

さて、React.js本体の解説に入る前に開発環境についても知っておくべきです。その説明をよりわかりやすくするべく、まずはReact.jsを使ったコンポーネントのコード例を示します。

var SampleComponent = React.createClass({
  render: function() {
    return (
      <div>
        This article is written by leader22
      </div>
    );
  }
});

このコード例は、単に次のHTMLを表示するだけのコンポーネントです。

<div>
  This article is written by leader22
</div>

一部、JavaScriptではない見慣れない記述があることに気付いたでしょうか? 少し迂回するのですが、開発環境について理解するには、React.js特有のコードについて知っておかなければなりません。

JSXとは

先のコード例の、この部分に注目してください。

render: function() {
  return (
    <div>
      This article is written by leader22
    </div>
  );
}

このHTMLのマークアップのような記述の部分がJSXと呼ばれるもので、Virtual DOMで扱うためのオブジェクトを簡潔に書けるようにした独自記法です。もちろん、JSXを使わずにReact.jsを使うことも可能ですが、コードの読みやすさの観点からおすすめしません。今後の記事についてもJSXを用いたコードで解説していきます。

ちなみに、JSXを使わない場合は、どういったコードになるかの例も載せておきます。

// jsxを使わない場合
render: function() {
  return React.createElement('a', { href: 'https://facebook.github.io/react/' }, 'Hello!');
}

// jsxを使う場合
render: function() {
  return [Hello!](https://facebook.github.io/react/);
}

このように単なるaタグのリンクを設置するだけでも冗長な記述が必要になることがわかります。階層の深いリストやテーブルを表示するケースを考えると、どちらがわかりやすいかは明白です。

そしてこのJSXを使うため、JSXをブラウザで実行できるJavaScriptに変換するために、開発環境にも一工夫が必要であるというわけです。

Babelを使う

JSXの変換には、トランスパイラであるBabel*を使う方法が公式としても紹介されています。

*注:Babel

Babelの導入や使い方に関しては、CodeGridでも過去に記事しているので、そちらを参照してください。

npm install --save-dev babel-preset-react

このようにReact.js用のプリセットが用意されているので、それを利用するだけです。

ES 2015

また、JSXと併せておすすめしたいのがES 2015*を使った記法です。

*注:ES 2015

ES 2015に関しては、CodeGridの次のシリーズなども参照してください。

前掲のシンプルなHTMLを表示するコード例を、ES 2015で書き換えたコードは、次になります。

class SampleComponent extends React.Component {
  render() {
    return (
      <div>
        This article is written by leader22
      </div>
    );
  }
}

この例ではそこまでありがたみがないですが、より複雑なコンポーネントを構築するようになってくると、Class構文だけでなく、Template strings、Destructuring assignmentやRest parametersなどの記法の便利さがわかってくると思います。

JSXの変換にBabelというトランスパイラを使うのであれば、併せてES 2015で記述すると良いと思います。

npm install --save-dev babel-preset-es2015

こちらもES 2015用のプリセットが用意されているので、それを利用しましょう。

ここまでの開発環境と、最後に紹介したサンプルを表示するデモを、以下のリポジトリに用意しておいたので、よろしければ参考にしてください。

これから始めるReact.js サンプルリポジトリ

おわりに

React.jsの名前はよく耳にするものの、実態がよくわからないと思っていた人も多かったのではないでしょうか。

肝心のReact.jsの使い方にはまだ触れられていませんが、今回の説明で少しでもReact.jsを触ってみようと思えた方がいれば幸いです。

ただこの記事を読んでも、依然としてとっつきにくい印象を持つ方もいらっしゃるかもしれませんが、それを踏まえた上でも使ってみる価値・可能性のあるライブラリであると筆者は考えています。

次回は、いよいよReact.jsを使ったコンポーネントの基本形について、実際のコードを見ながら解説していきます。

杉浦 有右嗣
PixelGrid Inc.
シニアエンジニア

SIerとしてシステム開発の上流工程を経験した後、大手インターネット企業でモバイルブラウザ向けソーシャルゲーム開発を数多く経験した。2015年にピクセルグリッドへ入社し、フロントエンド・エンジニアとして数々のWebアプリ制作を手掛ける。2018年に大手通信会社に転職し、低遅延配信の技術やプロトコルを使ったプラットフォームの開発と運用に携わっていたが、2020年ピクセルグリッドに再び入社。プライベートでのOSS公開やコントリビュート経験を活かしながら、実務ではクライアントにとって、ちょうどいいエンジニアリングを日々探求している。

Xにポストする Blueskyにポストする この記事の内容についての意見・感想を送る

全記事アクセス+月4回配信、月額880円(税込)

CodeGridを購読する

初めてお申し込みの方には、30日間無料でお使いいただけます