React のサンプルはすでにWeb 上に数多くあるが, Redux を使うものばかり。ここでは, やたらにパッケージを使わず、最低限のもので作っていく。
ソースコードはこちら; netsphere / react-by-examples · GitLab
今回のサンプルは、まずは永続化はせず、ボタンへの反応と、HTMLの表示のみを取り扱う。
React は, Webブラウザ上のユーザインタフェイスを構築するための JavaScriptライブラリ。Single Page Application (SPA) を作れる。
Facebook 社が開発している, オープンソース (ライセンスは MIT).
特徴:
import する。
2020年5月現在, JavaScript front-endフレームワークとしては不動の地位を占める。一時 Vue.js が迫ってきていたが, かわした。Angular は廃れつつある。
Fedora 32 には nodejs パッケージ, npm パッケージがある。CentOS 8 も同様。
| パッケージ | Fedora 32 | CentOS 8 | |
|---|---|---|---|
| nodejs | v12.16.1 | v10.19.0 | nodeコマンド |
| npm | v6.13.4 | v6.13.4 | npm, npx コマンド。 |
最近のパッケージマネジャの人気は yarn のようだが, あらかじめ入っている npm のほうを使う。[2022-09] Fedora 36 には `yarnpkg-1.22.17` がパッケージされている。
Create React App で雛形を作るのが簡単。CRA と略されることがあるが、いくら何でも略しすぎなのでは。
npx コマンドに次を渡す。これで、新しいアプリケーションの雛形を作ってくれる。
$ npx create-react-app アプリ名
アプリ名 に大文字を含めてはいけない (エラーになる)。同名のディレクトリが掘られて、次のファイルが生成される。
.gitignore
package-lock.json
package.json
public/
README.md
src/
reportWebVitals.js New! React v17 で生成.
serviceWorker.jspackage-lock.json ファイルも生成されるが、npm install で自動的に生成されるため, リポジトリに保存しなくてもよい。
プロジェクトの概要は package.json ファイルに記述する。コメントを記入できないのが辛い。dependencies が依存パッケージ。scripts が npm run のサブコマンド。あとは大体、書いてあるとおり。
Create React App で生成したアプリケーションのエントリポイントは public/index.html, src/index.js になる。いずれも react-scripts/config/paths.js で定められている。
src/index.js は, 次のコードで, App コンポーネントを呼び出す。大文字で始めるとコンポーネント, 小文字だと HTML タグと解釈される。
どのようにして JavaScript ファイルに書かれた XML/HTML のようなリテラル (これを JSX と呼ぶ。) が解釈されるのかについては、後述。
src/App.js は次のようにする。クラスを React.Component から派生させると, コンポーネントになる。構築子 constructor と render() メソッドが必須。
コンストラクタでは、必ず最初に super() を呼び出し, this.state を設定する。React では,「状態」は必ず state を通じて変更する。
render() は描画を担当する。このメソッド内で state を変更してはならない。戻り値として JSX を返す。
onIncr, onDecr がイベントハンドラ。この中で state を更新すると, 自動的に仮想 DOM が再計算されて, 必要なコンポーネントのレンダラが呼び出される。
React では, DOMを直接変更しないだけでなく, レンダラ呼出しも自動になっている。state の更新は, 必ず setState() メソッドで行う。これがきっかけになる。
$ npm install $ npm start
スクリーンショット
Reactの特徴の一つに、仮想DOM (Virtual DOM) がある。開発者は, render() ではいつでも, XML/HTMLコード片 (JSX) を完全に描画するように記述する。
React は, メモリ上に生成された仮想のDOMを保持する。この仮想DOM がどのように変化するかという差分を計算し、それに基づいて実際の Webブラウザ上に表示される DOM を書き換える、という2段構えになっている。
なので、変更点を直接更新するようなコードを書く必要がない。依存関係を気にしなくてよくなるため、非常に楽になる。
JSX も, React の特徴の一つ。JSX は往年の E4X ではない。というか, E4X はすでに廃れて、現代のWebブラウザでは文法エラーになってしまう。
JSX を含む JavaScript コードは, 実行前に Babel がコンパイルし、Webブラウザで動作する JavaScript に変換する。例えば, JavaScript に埋め込まれた次の文字列は、
<App onclick={this.foo} />
次のように変換される;
仮想DOM の計算は、render() を持つクラスとは別の文脈で実行される。JavaScript の this はダイナミックスコープのため, 呼出し側の文脈で決まる。そのため, this をあらかじめクラスに bind しておく必要がある。function 式でメソッドを定義してはならない理由がこれだ。ハンドラの定義は, アロー関数を使わなければならない。
このように JSX 式が展開されるので, return キーワードの後ろに行を替えて JSX を書く場合は return 直後に ( が必要。続けて書く場合は特に括弧がなくてもよい。