サーバーサイドエンジニアがReactを見て「jQueryとの違い」に納得した話
サーバーサイド開発を長く経験していると、JavaScript、特にjQueryの書き方に違和感を覚えることがある。
Reactの設計思想を調べると、その違和感の正体が見えてくる。
jQueryは「DOMを操作する」
jQueryの基本は次のようなコードになる。
$("#save").click(function () {
$("#title").text("保存しました");
});
イベントが発生したら、
- 要素を探す
- 要素を書き換える
- 必要であれば別の要素も更新する
という流れで画面を変更する。
つまり、主役はDOMである。
DOMを探すコードが増えていく
例えば一覧画面があるとする。
<ul>
<li><span>田中</span></li>
<li><span>鈴木</span></li>
<li><span>佐藤</span></li>
</ul>
「2番目のspanだけ更新したい」となると、
$("#users li").eq(1).find("span")
のようなセレクタを書くことになる。
HTML構造が変わればセレクタも修正が必要になる。
また一覧表示ではIDを付与できないため、
<span class="name">
のようにclassや親要素から目的のDOMを探すコードが増えていく。
DOMを探すための実装が徐々に複雑になるのは、jQuery時代によく見られた課題だった。
ReactはDOMを探さない
Reactでは考え方が逆になる。
const [count, setCount] = useState(0);
return (
<>
<button onClick={() => setCount(count + 1)}>
増やす
</button>
<p>{count}</p>
</>
);
クリック時に実行される処理は、
setCount(count + 1);
これだけである。
<p>を書き換えるコードは存在しない。
Reactはcountを利用している箇所を把握しており、必要なDOMだけを自動的に更新する。
主役はDOMではなくデータ
jQueryの流れは次のようになる。
クリック
↓
DOMを探す
↓
DOMを書き換える
↓
必要なら他のDOMも更新する
Reactは次のようになる。
クリック
↓
データを変更する
↓
Reactが必要なDOMだけ更新する
画面を書き換えるのではなく、データを変更することが中心になる。
サーバーサイドの発想に近い
例えばPHPでは、
return view('users', [
'users' => $users
]);
Bladeでは、
@foreach ($users as $user)
<li>{{ $user->name }}</li>
@endforeach
データからHTMLを生成することは、ごく自然な設計である。
Reactでも同じように、
{users.map(user => (
<li>{user.name}</li>
))}
データをもとに画面を構築する。
サーバーサイド開発者にとって、この考え方は比較的理解しやすい。
要素の種類が変わる場合も同じ
例えば、
-
<div>を<h1>へ変更する - 表示モードと編集モードを切り替える
といった場合でもDOMを直接操作しない。
return (
editing
? <input />
: <h1>タイトル</h1>
);
状態が変わるとReactが差分を判定し、必要なDOMだけを更新する。
「DOMをどう変更するか」ではなく、「現在の状態ならどのようなHTMLになるか」を記述する。
Vueも基本思想は同じ
VueもReactと同様に、データを中心に画面を構築する。
<h1 v-if="showTitle">見出し</h1>
<div v-else>本文</div>
showTitle.value = false;
これだけで表示内容は切り替わる。
Reactとの違いは主に記述方法であり、
- データを中心に考える
- DOMを直接操作しない
という設計思想は共通している。
Reactは新しい考え方なのか
Reactは革新的なフレームワークと紹介されることが多い。
しかし、サーバーサイド開発の視点では、
「モデルを変更し、ビューを再描画する」
という考え方はMVCやテンプレートエンジンで以前から一般的だった。
Reactの大きな特徴は、この考え方をブラウザ上へ持ち込んだ点にある。
そのため、サーバーサイド開発者ほど「新しい」というより「こちらの方が自然」と感じることも少なくない。
VueはReactの影響を受けて生まれた
VueはReactとは別系統の技術に見えるが、思想的にはReactから大きな影響を受けている。
Vueの作者であるEvan Youは、Reactの考え方に触れた上で、「Reactの良い部分を取り入れつつ、もっとHTMLに近い形で書けるフレームワーク」を目指してVueを作った。
つまりVueはReactとは無関係に生まれたものではなく、Reactの思想を参考にしながら、別の方向性へ発展したものと言える。
React:
- JavaScript中心でUIを書く
- JSXでコンポーネントを表現する
- UIもJavaScriptの一部として扱う
Vue:
- HTMLテンプレートを中心に書く
- template、script、styleを分ける
- HTMLを書く感覚を残したままコンポーネント化する
例えばReactでは、
function User({name}) {
return <h1>{name}</h1>;
}
Vueでは、
<template>
<h1>{{ name }}</h1>
</template>
のようになる。
どちらも「データが変われば画面が変わる」という同じ思想を持っているが、ReactはJavaScript寄り、VueはHTML寄りの設計になっている。
まとめ
Reactを理解すると、jQueryとの最大の違いはJavaScriptの文法ではなく設計思想にあることが分かる。
jQueryはDOMを操作する。
ReactやVueはデータを変更する。
その違いが、HTML構造の変更に強く、保守性の高いUIを実現している理由と言える。