Reactでよく使うJavaScriptの構文・メソッドまとめ|JSXから状態更新まで
Reactのコードが読み書きしづらいと感じる原因の多くは、ReactそのものではなくベースになっているJavaScriptとJSXの構文にあります。Reactは独自言語ではなく、アロー関数・分割代入・スプレッド構文といったモダンJavaScriptの書き方に、JSXという「JavaScriptの中にHTMLを書く」記法を足したものだからです。この記事では「react 構文」で実際に必要になる書き方を、コンポーネントの定義から条件分岐・リスト描画・状態更新まで、Reactでの使いどころとあわせて実例で整理します。
まとめ:Reactで押さえる構文とメソッド
先に全体像です。Reactの学習で優先度が高いのは次の構文とメソッドで、いずれもReact固有ではなくJavaScript/JSXの知識がそのまま使えます。
- アロー関数:コンポーネント本体とイベントハンドラ、コールバックの標準的な書き方。
- 分割代入:propsの受け取りと
useStateの戻り値展開で毎回使う。 - スプレッド構文:propsの一括展開と、状態を壊さない配列/オブジェクト更新の要。
- 三項演算子・論理積(&&):JSX内での条件付きレンダリング。
- map:配列からリスト要素を描画する定番。
keyの付与とセット。 - オプショナルチェーン(?.)・Null合体(??):未取得データの安全な参照。
- async/await:APIからのデータ取得を同期的な見た目で書く。
以降でそれぞれの構文を、Reactで使うときの注意点まで掘り下げます。まず前提となる「ReactとJavaScript/JSXの関係」から確認します。
Reactの構文はJavaScriptとJSXでできている
JSXは<div>Hello</div>のようにJavaScriptの中へタグを書く記法で、ビルド時にReact.createElement相当(React 17以降は自動JSXランタイムの_jsx)の関数呼び出しへ変換されます。つまりJSXの中括弧{ }にはJavaScriptの式がそのまま書けます。逆に文(if文やfor文)は式ではないため中括弧に直接は書けず、条件分岐は三項演算子、繰り返しはmapで表現します。この「中括弧の中は式だけ」というルールが、Reactで三項演算子とmapを多用する理由です。
現在のReactは関数コンポーネントとHooksが標準で、状態やライフサイクルはHooks(useStateやuseEffect)で扱います。クラスコンポーネントとcomponentDidMountなどのライフサイクルメソッドは既存コードの保守で見かける程度と考えて構いません。新しく学ぶなら関数コンポーネントの構文に絞るのが近道です。
Reactで必須のJavaScript構文
アロー関数:コンポーネントとイベントハンドラの書き方
コンポーネントもイベントハンドラもアロー関数で書くのが一般的です。onClickにインラインのアロー関数を渡すと、クリック時に実行する処理をその場に書けます。
const Counter = () => {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
{count}回クリック
</button>
);
};
onClick={handleClick}のように関数名だけを渡すと引数なしで呼ばれ、onClick={() => handleClick(id)}と包むと引数を渡せます。onClick={handleClick(id)}と書くとレンダー時に即実行されてしまうので、引数を渡すときはアロー関数で包むのが基本です。
分割代入:propsとuseStateの受け取り
propsはオブジェクトの分割代入で受け取ると、どの値を使うのかが引数の時点で分かります。useStateは[値, 更新関数]の配列を返すため、配列の分割代入で受け取ります。
const UserCard = ({ name, age }) => {
const [open, setOpen] = useState(false);
return (
<div>
<p onClick={() => setOpen(!open)}>{name}</p>
{open && <p>{age}歳</p>}
</div>
);
};
配列の分割代入は順序で決まるため、const [count, setCount]の名前は自由に付けられます。propsのオブジェクト分割代入は名前が一致している必要があり、初期値は({ name = "名無し" })のように指定できます。
スプレッド構文:propsの展開と状態の更新
スプレッド構文...は、propsの一括受け渡しと、状態を壊さない更新の両方で使います。まずpropsの展開です。
const props = { type: "text", placeholder: "氏名" };
return <input {...props} />;
状態更新では、既存の配列やオブジェクトをスプレッドで展開してから変更点だけを差し替え、新しい参照を作ります。setItems([...items, newItem])のように書くのが定番で、これがReactで再レンダリングを正しく起こすための土台になります(詳細は後述の状態更新の章)。「react スプレッド構文」で調べる場面のほとんどはこの2つです。
テンプレートリテラルとオプショナルチェーン:文字列組み立てと安全な参照
テンプレートリテラル(バッククォート)は、条件でクラス名を組み立てるときに便利です。className={`btn ${active ? "is-active" : ""}`}のように式を埋め込めます。
APIから受け取ったデータは、読み込み前はundefinedになりがちです。オプショナルチェーン?.とNull合体??(いずれもES2020)を使うと、値が無いときのエラーを避けつつ既定値を出せます。
const city = user?.address?.city ?? "未登録";
userやaddressがundefinedでも例外にならず、最終的に値が無ければ「未登録」になります。||ではなく??を使うと、0や空文字を有効な値として扱えます。
JSXでの条件分岐とリスト描画の構文
三項演算子と論理積による条件付きレンダリング
JSXの中括弧には式しか書けないため、条件分岐は三項演算子で書きます。「表示するか、しないか」だけなら論理積&&が簡潔です。
return (
<div>
{isLoggedIn ? <p>ようこそ</p> : <a href="/login">ログイン</a>}
{hasError && <p>エラーが発生しました</p>}
</div>
);
&&を使うときは左辺に数値を置かないよう注意します。{count && ...}はcountが0のとき画面に「0」と表示されてしまうため、{count > 0 && ...}と真偽値に直してから使います。
mapによるリスト描画とkeyの付け方
配列を並べて表示するときはmapで各要素をJSXへ変換します。このとき各要素に一意なkeyを付けます。keyはReactがどの要素が変わったかを判定する目印です。
return (
<ul>
{users.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
keyには配列のインデックスではなく、データが持つIDなど安定した値を使います。並べ替えや削除が起きるリストでインデックスをkeyにすると、表示と状態がずれる不具合の原因になります。
Reactでよく使うJavaScriptのメソッド一覧
「javascript よく使うメソッド」で求められるのは、配列とオブジェクトを加工する定番メソッドです。Reactではこれらを状態の整形や描画データの生成でそのまま使います。
配列を扱う非破壊メソッド:map・filter・reduce
| メソッド | 戻り値 | Reactでの用途 |
|---|---|---|
| map | 新しい配列 | リスト描画・要素の変換 |
| filter | 新しい配列 | 条件で絞り込み・削除 |
| find | 要素1つ | IDで対象を取得 |
| reduce | 単一の値 | 合計・集計 |
| some / every | 真偽値 | 条件判定・バリデーション |
| includes | 真偽値 | 存在チェック |
| concat | 新しい配列 | 配列を連結して追加 |
いずれも元の配列を変更しない非破壊的メソッドで、Reactの状態更新と相性が良いのが特徴です。たとえば削除はsetItems(items.filter((i) => i.id !== id))、加工はitems.map(...)で新しい配列を作って渡します。
オブジェクトを扱うメソッド:keys・values・entries
オブジェクトからキーや値の一覧が欲しいときはObject.keys・Object.values・Object.entriesを使います。Object.entries(obj).map(...)のようにmapと組み合わせると、オブジェクトをそのままリスト描画できます。
const scores = { 国語: 80, 数学: 92 };
return (
<ul>
{Object.entries(scores).map(([subject, score]) => (
<li key={subject}>{subject}: {score}</li>
))}
</ul>
);
entriesは[キー, 値]の配列を返すため、mapの引数でさらに分割代入して受け取ると読みやすくなります。
状態を壊さない書き方:破壊的メソッドと非破壊的メソッド
Reactで最も事故が多いのが状態の更新方法です。Reactは状態の「参照」が変わったかどうかで再レンダリングを判断するため、元の配列やオブジェクトを直接書き換える破壊的な操作は避け、新しい値を作って渡します。
破壊的メソッドと非破壊的メソッドの違い
| 操作 | 破壊的(状態に不可) | 非破壊的(状態に推奨) |
|---|---|---|
| 要素の追加 | push | スプレッド […arr, x] |
| 要素の削除 | splice | filter |
| 並べ替え | sort / reverse | […arr].sort() |
| オブジェクト更新 | 直接代入 obj.x = 1 | スプレッド {…obj, x: 1} |
破壊的メソッドは元データを直接変えるためメモリ効率では有利ですが、状態管理では参照が変わらず再レンダリングされない、あるいは表示が予期せず変わる不具合を招きます。sortやreverseも破壊的なので、状態の配列を並べ替えるときは[...arr].sort()とコピーしてから行います。
配列状態の不変更新:スプレッド・map・filter
配列の状態はスプレッド・map・filterで新しい配列を作って更新します。pushで直接追加すると参照が変わらず、画面が更新されないことがあります。末尾への追加は[...tasks, newTask]のほか、非破壊的なtasks.concat(newTask)でも書けます。
// 追加
setTasks([...tasks, newTask]);
// 特定要素の更新
setTasks(tasks.map((t) => (t.id === id ? { ...t, done: true } : t)));
// 削除
setTasks(tasks.filter((t) => t.id !== id));
更新のmapでは、対象の要素だけをスプレッドで複製して一部を差し替え、それ以外はそのまま返すのが定石です。
オブジェクト状態の不変更新:スプレッドで上書き
オブジェクトの状態も、既存のプロパティをスプレッドで展開してから変更点を上書きします。Object.assignも第1引数に空オブジェクト{}を渡せば非破壊的に使えますが、Reactではスプレッドで書くのが主流です。
setForm({ ...form, email: value });
ネストが深いオブジェクトは各階層をスプレッドする必要があり、煩雑になります。状態設計の段階で階層を浅く保つか、更新ロジックをuseReducerへ切り出すと見通しが良くなります。
非同期処理(async/await)とデータ取得の構文
APIからデータを取得する非同期処理は、async/awaitで同期的な見た目に書けます。useEffectの中で呼ぶときは、内側にasync関数を定義して呼び出すのが安全な書き方です(useEffectのコールバック自体をasyncにはできません)。
useEffect(() => {
const load = async () => {
try {
const res = await fetch("/api/users");
const data = await res.json();
setUsers(data);
} catch (e) {
setError("取得に失敗しました");
}
};
load();
}, []);
取得中・失敗・成功で表示を分けるため、データ本体と読み込み状態・エラーを状態として持つのが定番の構成です。データ取得の設計をさらに深掘りするならフロントエンド開発者が理解すべきAsync Reactの技術的背景と全体像も参考になります。
React Hooksで状態と副作用を書く構文
Hooksは関数コンポーネントの中で状態や副作用を扱う仕組みで、React 16.8(2019年)で追加されました。名前がuseで始まる関数がHooksで、呼び出す場所にルールがあります。
useStateとuseEffectの基本形
useStateは状態と更新関数を配列で返し、useEffectは副作用(データ取得やイベント登録など)を扱います。useEffectの第2引数(依存配列)に指定した値が変わったときだけ再実行されます。
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `${count}回`;
}, [count]);
依存配列を空[]にすると初回のみ、省略すると毎レンダー実行されます。副作用で登録したイベントやタイマーは、returnで後片付け(クリーンアップ)を返して解除します。
Hooksを使うときのルール
Hooksは「コンポーネントの最上位でのみ呼ぶ」「if文やループの中で呼ばない」という2つのルールがあります。呼ぶ順序が毎回同じでないと、Reactが状態を正しく対応付けられないためです。より詳しい導入はReactフックの基本と導入:React 16.8で追加された新機能の概要、DOM参照や値の保持に使うuseRefはReactのuseRefの使い方|useStateとの違い・DOM参照・値の保持を実例で解説で扱っています。
初心者がつまずくReact構文のミスと避け方
最後に、構文自体は正しくてもReactで動かなくなる典型的なミスを挙げます。エラーメッセージが出ないぶん原因に気づきにくいので、先に知っておくと詰まりにくくなります。
- 状態を直接書き換える:
tasks.push(x)やform.name = vは参照が変わらず再レンダリングされません。必ず新しい値を作って更新関数へ渡します。 - keyにインデックスを使う:並べ替え・削除のあるリストでは表示崩れの原因。安定したIDを使います。
- 数値と&&を組み合わせる:
{items.length && ...}は要素が0件のとき「0」が表示されます。items.length > 0 &&とします。 - useEffectの依存配列の付け忘れ:使っている値を依存配列に入れないと、古い値を参照し続ける(古いクロージャ)不具合になります。
いずれも「状態は書き換えず作り直す」「JSXの中括弧には真偽値を渡す」という2点を意識すると大半を防げます。構文を暗記するより、なぜその書き方をするのか(不変性と式のルール)を押さえるほうが応用が利きます。
よくある質問
Q. react 構文とは何を指しますか?
Reactを書くときに使うJavaScriptとJSXの記法を指します。React独自の文法は多くなく、アロー関数・分割代入・スプレッド構文などのモダンJavaScriptに、JSX(JavaScriptの中にタグを書く記法)と条件分岐/リスト描画の書き方を加えたものが中心です。
Q. Reactでよく使うJavaScriptのメソッドは?
配列のmap・filter・find・reduce、真偽判定のsome/every/includes、オブジェクトのObject.keys/entriesが定番です。いずれも元データを変えない非破壊的メソッドで、状態更新やリスト描画に使います。
Q. react スプレッド構文はどう使いますか?
propsの一括展開(<input {...props} />)と、状態を壊さない更新([...arr, x]や{...obj, key: v})の2つが主な用途です。既存の値を展開して新しい参照を作ることで、Reactの再レンダリングが正しく起きます。
Q. クラスコンポーネントの構文はもう使いませんか?
新規開発では関数コンポーネントとHooksが標準です。componentDidMountなどのライフサイクルメソッドは既存コードの保守で見かける程度で、これから学ぶなら関数コンポーネントに絞って問題ありません。
Q. React 16.8とは何が変わったバージョンですか?
2019年のReact 16.8でHooksが追加され、クラスを使わずに関数コンポーネントで状態や副作用を扱えるようになりました。現在のReactの書き方の土台になっているバージョンです。最新の仕様や推奨は公式ドキュメントで確認してください。