React が好きです。
どのくらい好きかというと未就学児の頃は「大きくなったら React と結婚する!」と言っていたくらいです(大嘘)。
しかし好きとは言っても私の理解度は「見た目は何となく作れるよ」というスーパーウルトラ低解像度に留まっているので、大好きな React についてもっともっと知っていくべく公式ドキュメントに挑みたいと思います。
ベータ版のチュートリアル で扱われているように関数コンポーネントがよりモダンなのでクラスコンポーネントについては割愛しています。
今回紹介している「フック」の登場によって関数コンポーネントとクラスコンポーネントの機能的な違いはなくなり、関数コンポーネントの方がシンプルに書けます。
React ってなに?
React – A JavaScript library for building user interfaces
React は UI を構築するための JavaScript ライブラリです。
かっこいいのでスクショは英語版にしたのですが、日本語だとなぜかクソダサ不揃いフォントになっています。な ぜ
▼ 「なんで React がフレームワークじゃなくてライブラリなんだろう?」と思った方はよければこちらもご覧ください。
React というライブラリの性質を知るべくスクショを貼ったトップページについて見ていきますが、あくまでトップページなのでライブラリの特性というよりは「私を使って開発するとこんなメリットがありますよ!」という営業トークかなと思います。しかし React が好きなのでちゃんと読みますよ。
React には3つの特徴があるようです。
- 宣言的な View
- コンポーネントベース
- 一度学習すれば、どこでも使える
宣言的な View
宣言的な View
React は、インタラクティブなユーザインターフェイスの作成にともなう苦痛を取り除きます。アプリケーションの各状態に対応するシンプルな View を設計するだけで、React はデータの変更を検知し、関連するコンポーネントだけを効率的に更新、描画します。
宣言的な View を用いてアプリケーションを構築することで、コードはより見通しが立ちやすく、デバッグのしやすいものになります。
React – ユーザインターフェース構築のための JavaScript ライブラリ
早速わからないのですが、 View って何でしょう🤔
View といえば React Native のコンポーネントだと思うのですが、React における View はおそらく「見た目」のことでしょうか? 最初が大文字の「View」になっているので用語のような気がするのですが…分かる方は教えていただけると嬉しいです。
React はインタラクティブな操作を機能として持つアプリを作成するのにとても便利ですね。
Vanila で DOM 操作してイベントを追加する手順はこんな感じです。
-
document.createElement
で要素作成 - 関数作成
- 要素に
document.addEventListner
メソッドでイベントハンドラとして関数を追加 -
document.appendChild
などで既存の HTML にくっつける
いちいちメソッド名が長いのも特徴ですね。
それが React であればこんなふうにコードを書けます。
function MyButton() {
function handleClick() {
alert('You clicked me!');
}
return (
<button onClick={handleClick}>
Click me
</button>
);
}
// 引用: https://beta.reactjs.org/learn
Vanila の DOM 操作のように手取り足取り命令せずとも、定義した見た目に動作させたい関数を渡すだけであとはよしなにやってくれるという何ともシンプルな書き方です。こういった書き方の UI を宣言的 UI と言います。コードが大規模になってくると明らかに管理にかかる手間が違ってきますよね。
また React の特徴として、データの状態 = state に変更があると自動的に変更を反映してくれるという点が挙げられます。
コンポーネントベース
コンポーネントベース
自分自身の状態を管理するカプセル化されたコンポーネントをまず作成し、これらを組み合わせることで複雑なユーザインターフェイスを構築します。
コンポーネントのロジックは、Template ではなく JavaScript そのもので書くことができるので、様々なデータをアプリケーション内で簡単に取り回すことができ、かつ DOM に状態を持たせないようにすることができます。
React – ユーザインターフェース構築のための JavaScript ライブラリ
マークアップとロジックを別々のファイルに書いて人為的に技術を分離するのではなく、React はマークアップとロジックを両方含む疎結合の「コンポーネント」という単位を用いて関心を分離します。
JSX の導入 – React
React を理解する上で絶対にベースとなる重要概念がコンポーネントです。
component という英単語には「要素、部品、構成要素」などの意味があります。
React のコンポーネントは UI を構成する1つのパーツであり、JSX によって生成された React 要素を返す関数です。ロジックと見た目のマークアップを持ちます。
// これ全部が1つのコンポーネント
function MyButton() {
// ロジックを JavaScript で書く
function handleClick() {
alert('You clicked me!');
}
// UI は return 文の中に書く
return (
<button onClick={handleClick}>
Click me
</button>
);
}
// 引用: https://beta.reactjs.org/learn
MyButton
となっているように、コンポーネントは全て大文字から始めるのがルールとなっています。HTML タグは必ず小文字スタートなので絶対に名前が被らないようしているのでしょう。
またコンポーネントは上のようにボタン1つだけでも作れますが、ページ全体を1つのコンポーネントで表現してしまうこともできます。どのように分割するかは設計思想によりけりです。
作成したコンポーネントは他のコンポーネントにネストして組み込めます。
export default function MyApp() {
return (
<div>
<h1>Welcome to my app</h1>
<MyButton />
</div>
);
}
}
// 引用: https://beta.reactjs.org/learn
export default
を使うことで「このページで作成した、他のファイルでも読み込みたいメインのコンポーネントはこれだよ」と示すことができます。
▼ export がピンとこない方はこちらもご覧ください。
一度学習すれば、どこでも使える
一度学習すれば、どこでも使える
React と組み合わせて使用する技術に制限はありません。React を使って新しい機能を追加する際に、既存のソースコードを書き換える必要はありません。
React は Node を使ったサーバ上でもレンダーできますし、React Native を使うことでモバイルアプリケーションの中でも動きます。
React はフレームワークではなくライブラリなので、さまざまな他のライブラリと一緒に使用することができます。
またJavaScript のライブラリである React Native を使うことで iPhone と Android のアプリ開発も行えます。文法は React と異なる部分も多いですが、ベースとなる考えは宣言的UI & コンポーネントなので React を使ったことがあればすんなり理解できるはずです。
JSX ってなに?
JSX は JavaScript XML の略であり、.jsx
という拡張子を持ちます。 HTML と JavaScript を組み合わせて書けることが特徴です。React も JSX に対応しています。
ただ別に JavaScript(.js
) でも React は書けるので、JSX を使うかはエンジニアに任されています。公式ドキュメント には「JSX 使うと色々と便利だよ〜」とは書いてありましたが、かなり論争があるようです。
JSX では HTML に似たマークアップを使っていますが、HTML よりもかなり厳しいです。
HTML では多少閉じタグがなかったり、タグの名前が間違っていたりしても許してもらえるのですが、JSX は許してくれません。また2つ以上のタグを返すことはできないので、1つのタグという扱いになるように空のタグで囲む必要があります。
function AboutPage() {
return (
<>
<h1>About</h1>
<p>Hello there.<br />How do you do?</p>
</>
);
}
コンパイルされると JSX の式は JavaScript の関数呼び出しに変換され、JavaScript オブジェクトと評価されます。
React 要素ってなに?
React 要素は JSX から生成され、 root.render()
によって DOM要素 に変換され、HTML に反映されます。
const root = ReactDOM.createRoot(
document.getElementById('root')
);
const element = <h1>Hello, world</h1>; // まだ React 要素
root.render(element); // DOM 要素
// 参考: https://ja.reactjs.org/docs/rendering-elements.html
仮想 DOM ってなに?
その名の通り仮の DOM のことです。React だけで使われている概念ではなく、React でも使用されている重要概念、と言った方がいいでしょう。
メリットとしてパフォーマンスの向上が挙げられます。
DOM を操作するとき、例えば親ノードに対する変更を反映させるためには子ノードも全て書き換える必要があります。仮想 DOM を編集してから DOM を構築する、というステップを踏む仮想 DOM では、差分を見極めて必要な部分だけ変更を反映することができます。
map
など繰り返し処理を使って要素を作成すると、 Each child in an array or iterator should have a unique "key" prop.
というエラーが出たことはないでしょうか? このエラーは「これから先も変更があったとき反映が大変になっちゃうから、要素を識別できるように key
の props をつけてね」という意味です。
フックってなに?
フックとは、関数コンポーネントに state やライフサイクルといった React の機能を “接続する (hook into)” ための関数です。フックは React をクラスなしに使うための機能ですので、クラス内では機能しません。
フック早わかり – React
フックはクラスコンポーネントで使えていた機能を関数コンポーネントでも使えるようにするものです。
クラスコンポーネントの場合は例えば this.state
の形で使えていた React の機能を関数コンポーネントでも使う場合に useState
が使えます。
元々クラスコンポーネントしかなかったところに関数コンポーネントが導入されましたが、機能が限られてしまうと言う問題がありました。現在はフックがあるので両者に差はありません。よりシンプルにかける関数コンポーネントを使うのがいいのではないでしょうか。
state 管理ってなに?
こちらでまとめました。
useRef ってなに?
こちらでまとめました。
useEffect ってなに?
React 最適化についてまとめたこちらの記事の最後で扱っています。
まとめ
- React は UI を構築するための JavaScript ライブラリ
- ライブラリなので様々な他のライブラリと組み合わせて使える
- 宣言的 UI を採用しており、管理にかかる負担が少ない
- コンポーネントを単位として考える
- React Native を使うとスマホアプリの開発もできる
- JSX は文法に厳しい
- JSX から生成されているのは HTML ではなく React 要素
- 仮想 DOM を編集 → DOM を構築、とすることで、差分を見極め効率的に変更を反映できる
- フックとはクラスコンポーネントで使えていた機能を関数コンポーネントでも使えるようにするもの
参考資料
- React – ユーザインターフェース構築のための JavaScript ライブラリ
- なぜクラスコンポーネントより関数コンポーネントが推奨されるのか?
- Quick Start
- Proposal: [react][breaking] Only .js files should contain JSX. by KevinGrandon · Pull Request #985 · airbnb/javascript
- React Native · Learn once, write anywhere
- JSX の導入 – React
- 仮想 DOM と内部処理 – React
- 差分検出処理 – React
- 仮想DOMの時代はもう終わり? | Welcome to Monstarlab’s Engineering Blog