2年ぶりくらいに業務で React をやることになったので、個人的なおさらい用です。
#React ってなに?
React は UI を作るためのライブラリです。
UI は「コンポーネント」という概念によって記述することになります。
基本的にはユーザーが自由に実装した「カスタムコンポーネント」を UI 毎に作成し、それを組み立てることで Web アプリケーションを構築することができます。
HTML の DOM 要素を利用したコンポーネントを作成するには React.DOM
オブジェクトを利用しすることもできます。
React の特徴
以下の4つが React の特徴です。
- リアクティブ
- 仮想 DOM
- Component ベース
- JSX
##リアクティブであること
ユーザーの操作やデータの変化を監視して、その変化によって自分で設定した処理に沿うように自動的に画面を再描画してくれます。
##仮想 DOM
jQuery や一般的な JavaScript では DOM 操作を「最適化して」処理を記述する必要があります。
DOM 操作は非常にコストの大きい処理です。近年の Web 開発では非常に多くの DOM 操作を必要とします。ユーザーの操作に応じて多くのデータを更新したり、見た目を変化させるためです。
React では、仮想 DOM という React が内部に持っている独自の DOM 情報と実際の DOM を効率的な方法で比較し、差分を変更してくれるので、処理が非常に軽くなります。
注意点としては、DOM 操作を必要としないわけではなく、純粋な JavaScript を最適化した処理よりも早くなることはありません。
ですが規模の大きいアプリケーションでは全てを最適化することは現実的ではありません。
あくまで、楽にいい感じにしてくれるもの、と捉えておくと良さそうです。
##Component ベース
React ってなに? でも書いたように、React はコンポーネントを作って、それを組み立てて Web 開発を行います。
では、それによるメリットはなんでしょうか。
それは、「保守性」「再利用性」「デザインシステムとの相性の良さ」が挙げられます。
###保守性
コンポーネント単位で開発していくと、しっかりと設計を行うことでコンポーネントに「単一責任の原則」が生まれます。
機能・見た目・状態などをそのコンポーネントに閉じ込め、外から変更をできなくすることができます。
それにより機能の所在が明らかに別れてデバッグがしやすくなります。
###再利用性
保守性で書いた単一責任の原則は再利用性の向上にも寄与します。
もしそのコンポーネントが複雑な依存関係を持っていない場合、複数の場所でコンポーネントを再利用することが可能となり、開発スピードが上がります。
###デザインシステムとの相性の良さ
近年ではアプリケーション開発にデザインシステムを持ち込むことが多くなっています。
例えば Atomic Design のように Web アプリ全体をコンポーネントで分け、それを役割によって分類・管理し、それを組み合わせていくようなことが、コンポーネントベースであれば簡単に行うことができます。
##JSX
JSX も React の特徴の一つです。
JSX は JavaScript の拡張構文で、JavaScript の中に文書構造を持ち込むことができるという特徴があります。
簡単にいうと、JavaScript の中で HTML が書けて、属性や文字列に変数やメソッドを埋め込むことができるというものです。
なぜ JSX が必要なのか、不思議に思う方もいると思います。
HTML と JavaScript は分離して管理すべきだ!という思想が広く定着していたこともあります。
ですが近年の Web 開発では、データをサーバーから API で動的に表示させることが非常に多いです。
ほぼ実態のない HTML 要素に JavaScript の処理を紐付けることで、意味のない空の div
や空の a
タグが散乱し、文書構造もなにもあったものではない状況です。
そのために WAI-ARIA という仕様が取り沙汰されましたが、先程も述べたように近年の Web 開発では「動的に」表示が変化します。つまり内容が変わってしまうのです。
それならば、JSX で記述する WAI-ARIA の状態を管理してあげたほうが、より現実的なセマンティクス Web の実現につながるのではないかという意見もあり、採用しているプロダクトが多いようです。
Accessible Rich Internet Applications (WAI-ARIA) 1.2 日本語訳
なんで React や Vue のような JavaScript ライブラリが人気なのか
ここまで React の特徴を書いた中ですでに React に対して「高機能な近年の Web アプリ開発に適していること」を感じた人も多いのではないでしょうか。
- 肥大化した処理の DOM 操作の最適化
- コンポーネントによる管理のしやすさ
- JSX によるアプリケーション化した Web の管理の最適化
これらは Vue などの、どのライブラリにも大抵は共通しており、細かな振る舞いやスケーリングの思想の違いによって使い分けられています。
#コンポーネントの最小構成
最小限の構成は render()
という、カスタムコンポーネント(ユーザーが定義したコンポーネント)に必須のメソッドで React のコンポーネントを返す形です。
コンポーネントに「プロパティ(props)」を追加すると、その値に応じてふるまいを変更できます。
追加したすべてのプロパティは this.props
でアクセスすることができ、例えば、親コンポーネントから、子孫コンポーネントに情報を渡す際に非常に便利です。
また、コンポーネントには propTypes
というプロパティも追加でき、そのコンポーネントが受け付けるプロパティの名前や値の型を宣言することができます。
必須ではありませんが、データを検証することができるし、コンポーネントの仕様としても機能するため、メンテナビリティが向上するため推奨されています。
更に、 getDefaultProps()
というメソッドを作成して設定することで、省略可能なプロパティのデフォルト値をオブジェクトで返すこともできます。
プロパティは変更ができないデータ(immtable data)として扱われ、getDefaultProps()
で定義したデフォルト値か、親コンポーネントから受け取った値のどちらかを持っています。
状態の管理(ステート)
コンポーネントは描画する際にステートのデータを利用します。
ステートに変化があると、React は自動的に UI を再構成してくれます。つまり、最初に render()
で初期描画をしたら、ユーザーの操作やデータの更新を見て render()
メソッドの中で設定した表示方法に沿って UI を自動的に最適化してくれるというわけです。
ステートにアクセスするには this.state
オブジェクトを使うことでコンポーネントからアクセスできます。
ステートを変更するには this.setState()
を使い、このメソッドが呼ばれると render()
メソッドを呼び出して UI を更新してくれます。
ステートはコンポーネント固有のデータで、データはコンポーネントからコンポーネントへ受け渡すことはしません。
コンポーネントが持つプライベート変数のようなものだと認識しておけばよさそうですね。
#まとめ
ここまでお読みいただきありがとうございます!
この記事を読んで実際に触ってみたいと思った方はぜひ公式のチュートリアルを試してみてください!
導入からちょっとしたゲームの作成ができて、時間もそれほど必要ありません。(そして日本語です!)
誤りや認識の違いなどがありましたらご指摘いただけると助かります!