React入門 — HTMLとの違い、JavaエンジニアがReactを始める前に知っておきたいこと
はじめに
Javaでバックエンドを書いてきたエンジニアが、フロントエンドに足を踏み入れる時に最初の壁になるのが React です。
「HTMLとCSSは分かる。でもReactって何が違うの?」という疑問を持ちながら進めると、JSXやコンポーネントの概念でつまずきます。
この記事では 「なぜReactが生まれたのか」 から整理することで、Reactの設計思想を掴みやすくします。
Reactが生まれる前の世界
昔のWeb開発はこうでした。
<!-- HTML -->
<p id="count">0</p>
<button onclick="increment()">+1</button>
// JavaScript
let count = 0;
function increment() {
count++;
document.getElementById('count').textContent = count; // 自分でDOMを操作
}
問題点:
- 状態(
count)とUI(<p>の中身)を自分で同期させなければならない - 画面の要素が増えるほど、「どこを更新するか」の管理が複雑になる
- JavaScriptとHTMLが分散していて、関連するコードが散らばる
Reactが解決したこと
Reactは「状態が変わったら、UIは自動で更新される」という仕組みを提供しました。
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0); // 状態を宣言
return (
<div>
<p>{count}</p>
<button onClick={() => setCount(count + 1)}>+1</button>
</div>
);
}
ポイント:
-
countが変わると、Reactが自動で画面を再描画する - 「どのDOM要素を更新するか」を自分で書かなくていい
- 状態とUIが同じファイルにまとまっている
Reactの3つのコア概念
1. 宣言的UI(Declarative UI)
「画面がどう見えるべきか」を宣言するスタイルです。
// 命令的(従来のJS): 「countをここに書け」という手順を指示
document.getElementById('count').textContent = count;
// 宣言的(React): 「countはこう表示される」という状態を宣言
<p>{count}</p>
Javaで例えると、命令的はforループ、宣言的はStream APIのような関係です。
// 命令的
List<String> result = new ArrayList<>();
for (String s : list) {
if (s.length() > 3) result.add(s);
}
// 宣言的(Stream)
List<String> result = list.stream()
.filter(s -> s.length() > 3)
.collect(Collectors.toList());
2. コンポーネント
UIを「部品」に分けて管理します。
// ボタン部品
function Button({ label, onClick }) {
return <button onClick={onClick}>{label}</button>;
}
// ヘッダー部品
function Header() {
return (
<header>
<h1>マイアプリ</h1>
<Button label="ログイン" onClick={() => console.log('login')} />
</header>
);
}
Javaのクラスに近い発想です。1コンポーネント = 1責務。
3. 仮想DOM(Virtual DOM)
Reactは「仮想のDOMツリー」をメモリ上に持ち、状態が変化した時に「前後の差分だけ」を実際のDOMに反映します。
状態変化
↓
仮想DOMを再構築
↓
前の仮想DOMと差分を比較(差分検出)
↓
変わった部分だけ実際のDOMを更新
これによって、大量のDOM操作が発生してもパフォーマンスが落ちにくくなります。
JSXとは何か
ReactのコードにはHTML風の記法が出てきます。これが JSX です。
// これはJSX(JavaScriptでもHTMLでもない)
const element = <h1>Hello, World!</h1>;
// コンパイルされるとこうなる(実際には書かなくていい)
const element = React.createElement('h1', null, 'Hello, World!');
JSXはJavaScriptの拡張構文で、ブラウザに届く前にJavaScriptに変換されます。見た目はHTMLですが、JavaScriptの中に書けるのが特徴です。
注意点:
// HTMLとの違い
<div class="box"> // HTML
<div className="box"> // JSX(classはJSの予約語なのでclassName)
<label for="name"> // HTML
<label htmlFor="name"> // JSX(forも予約語)
Reactを始めるのに必要なもの
# Node.js がインストールされていれば以下でOK
npx create-react-app my-app
cd my-app
npm start
または最近は Vite を使うことも多いです:
npm create vite@latest my-app -- --template react
cd my-app
npm install
npm run dev
JavaエンジニアがReactで感じるギャップ
| Java感覚 | Reactの実際 |
|---|---|
| クラスベースで設計 | 関数コンポーネントが主流(クラスコンポーネントは古い) |
| 型が強制される | JSは型なし(TypeScriptを別途導入) |
| コンパイルエラーで気づく | 実行時エラーになることも多い |
| 変数はミュータブルが普通 | 状態の直接変更はNG(immutableに扱う) |
特に「stateを直接変更してはいけない」はJavaのMVCに慣れたエンジニアがよくやるミスです。
// NG: stateを直接変更
const [list, setList] = useState([1, 2, 3]);
list.push(4); // これではReactは再描画しない
// OK: 新しい配列を作って渡す
setList([...list, 4]);
まとめ
| 概念 | ひとこと |
|---|---|
| 宣言的UI | 「どう見えるか」を書く。手順は書かない |
| コンポーネント | UIを部品に分けて管理 |
| 仮想DOM | 差分だけ更新するため高速 |
| JSX | JSの中にHTML風の構文が書ける拡張記法 |
| State | 変更をsetState経由で行うことで再描画が走る |
次回はJSXの書き方をもう少し深掘りします。