第1回
なぜReactなのか:コンポーネント思考と宣言的UIを理解する
HTMLのコピペ地獄からコンポーネント思考へ。jQueryとReactの違い、宣言的UIとは何かを対話形式でゼロから解説。
·12分で読める
たける
Reactって結局、HTMLとJavaScriptで書けることをわざわざ難しくしてるだけじゃないですか?
りこ
実際に手を動かして確認してみましょう。まず、登場人物紹介ページをHTMLで作ることを想像してみて。キャラクターが5人いるとして、どう書く?
たける
カードのHTMLを5回書く……あ、コピペして名前や説明文を変えていく感じですかね。
りこ
そう。そしてカードのデザインを変えたくなったら?
たける
5箇所全部直す……
HTMLで書くとこうなる
5人分のキャラクターカードを素のHTMLで書くとこうなる。
<!-- index.html -->
<div class="character-card">
<img src="/characters/riko.jpg" alt="大沢りこ">
<h2>大沢りこ</h2>
<p>フロントエンドチームリーダー</p>
<p>13年のエンジニア歴を持つ。...</p>
</div>
<div class="character-card">
<img src="/characters/takeru.jpg" alt="宮本たける">
<h2>宮本たける</h2>
<p>インターン</p>
<p>元商社マン。...</p>
</div>
<!-- あと3人分、同じ構造が続く -->これでも動く。でも、3つの問題がある。
- 修正が大変:カードのHTMLを変えたら全員分直す必要がある
- 追加が大変:6人目が増えたら、また同じHTMLを書く
- データとUIが混ざっている:「りこのプロフィール」と「カードの見た目」が同じ場所にある
Reactで書くとこうなる
Reactでは「カードの形」と「カードの中身(データ)」を分離できる。
// カードの「形」を1回だけ定義する
const CharacterCard = ({ name, role, image, bio }) => (
<div className="character-card">
<img src={image} alt={name} />
<h2>{name}</h2>
<p>{role}</p>
<p>{bio}</p>
</div>
)
// データを配列で持つ
const characters = [
{ id: 'riko', name: '大沢りこ', role: 'フロントエンドチームリーダー', image: '/characters/riko.jpg', bio: '...' },
{ id: 'takeru', name: '宮本たける', role: 'インターン', image: '/characters/takeru.jpg', bio: '...' },
// ...
]
// 配列をループして全員分を表示
const CharactersPage = () => (
<div>
{characters.map(c => (
<CharacterCard key={c.id} {...c} />
))}
</div>
)
たける
カードを1回書いて、あとはデータで制御するってことですね。カードのデザインを変えたら全員に反映されるし、人を追加するにはデータを1行追加するだけ。
りこ
それがコンポーネント思考。「繰り返す形」を部品にして、データを差し込む。
コンポーネントとは何か
コンポーネントとは、UIの部品のこと。
CharacterCard というコンポーネントは「キャラクターを1人分表示する方法」を知っている。誰を表示するかは、渡されるデータ(props)で変わる。
このサイト全体もコンポーネントの組み合わせでできている。
App
├── Header(ナビゲーション)
├── CharactersPage(登場人物ページ)
│ ├── RosterCard × 5(ロスター選択)
│ └── CharacterCard(詳細カード)
│ ├── 画像エリア
│ └── プロフィールエリア
└── Footerそれぞれの部品が独立していて、別の場所でも使い回せる。
jQueryとの違い
「jQueryでも同じことができるじゃないか」という疑問が出るかもしれない。違いはUIの更新の考え方にある。
jQueryの場合:「どう変えるか」を命令する
// クリックしたら、この要素のテキストを変えろ
$('#count').text(count + 1);
// この要素を表示しろ
$('#modal').show();
// このリストに要素を追加しろ
$('#list').append('<li>' + item + '</li>');画面をどう操作するかを1ステップずつ命令する。UIが複雑になると、どこで何を変えたか追うのが難しくなる。
Reactの場合:「何を表示するか」を宣言する
// countが何であれ、常にこのUIを表示する
return <p>クリック回数: {count}</p>
// isOpenの値によって、常にこう表示する
return isOpen ? <Modal /> : null
// itemsの中身が何であれ、常にこうマッピングする
return items.map(item => <li key={item.id}>{item.name}</li>)「今の状態(state)に基づいて、こういうUIを表示する」と宣言するだけ。状態が変わったらReactが差分を計算して、変わった部分だけ自動で更新する。
たける
jQueryは「これをこう変えろ」、Reactは「こういう状態のときはこう見せる」ってことですよね。
りこ
正確。だからReactは「宣言的UI」と呼ばれる。UIが複雑になるほど、この考え方の差が効いてくる。
たける
登場人物ページで画像をクリックしたら別の画像に切り替わるやつ、Reactだとどう書くんですか?
りこ
「選択中の画像番号」をstateで持って、それに応じて表示する画像を変えるだけ。第9回でやる。今はまず環境を作ろう。
まとめ
- コンポーネント:UIの部品。1回定義して、データを変えながら何度でも使い回す
- props:コンポーネントに渡すデータ。コンポーネントの外から「中身」を差し込む
- 宣言的UI:「今の状態ではこう見える」を定義する。どう変えるかはReactに任せる
- 画面が複雑になるほど、コンポーネント思考と宣言的UIの恩恵が大きくなる
次の第2回では、開発環境を整える。Node.jsのインストールから、ブラウザでコードの変更がリアルタイムに反映されるまでをやる。