React
Reactの基本概念
| 概念 | 説明 |
|---|---|
| コンポーネント | UIを構成する部品。関数コンポーネントが主流 |
| JSX | JavaScript内でHTMLライクな記述をする構文 |
| 状態管理 | useState を使ってコンポーネントの状態を管理 |
| イベント処理 | onClick などでユーザーの操作をハンドリング |
| 副作用処理 | useEffect はReact の外にある仕組みと同期させるためのもの。API 通信には使わない |
| コンポーネント間通信 | props を使ってデータを親から子へ渡す |
基本的なコード例
🔹 1. コンポーネントの作成
Reactではコンポーネントを作成してUIを構築します。
function Greeting() {
return <h1>こんにちは、React!</h1>;
}
export default Greeting;🔹 2. 状態管理 (useState)
useState を使って、カウンターを作成する例。
import { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<h1>カウント: {count}</h1>
<button onClick={() => setCount(count + 1)}>増やす</button>
</div>
);
}
export default Counter;🔹 3. 副作用処理 (useEffect)
この例は、いまの React 公式の推奨とは違う。 2026-08-31 に react.dev を取得して確認した。下記「useEffect でデータを取得しない」を先に読む。
APIからデータを取得して表示する。
import { useState, useEffect } from "react";
function FetchData() {
const [data, setData] = useState([]);
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/posts")
.then((res) => res.json())
.then((json) => setData(json.slice(0, 5)));
}, []);
return (
<div>
<h2>データ一覧</h2>
<ul>
{data.map((item) => (
<li key={item.id}>{item.title}</li>
))}
</ul>
</div>
);
}
export default FetchData;useEffect でデータを取得しない
Effect は「逃げ道」であって、React の外にある仕組みと同期させるためのもの。
外部の仕組みと同期させようとしているのでなければ、おそらく Effect は要らない。
上の例のように Effect の中で fetch を書くと、4つの問題がついてくる。
| 問題 | 中身 |
|---|---|
| 競合状態 | 応答が送った順に返るとは限らない。上の例はこの対策が入っていない |
| サーバーで動かない | サーバーが返す最初の HTML には、データではなくローディング表示しか入らない |
| ネットワークの滝 | 親が取り終わってから子が取り始める。並行にならない |
| 先読みもキャッシュもない | 再マウントのたびに取り直す |
推奨は、フレームワークの取得機構を使うこと。 クライアントだけで完結させるなら、TanStack Query や useSWR のような キャッシュを持つ仕組みを使う。
自前で書くなら、最低限、後片付けで競合状態を潰す。
useEffect(() => {
let ignore = false;
fetch(url)
.then((res) => res.json())
.then((json) => {
if (!ignore) setData(json);
});
return () => {
ignore = true;
};
}, [url]);カスタムフックに切り出しておくと、後で効率のよい取得方法へ移りやすい。
そもそも Effect が要らない場面
2つは、書く前に疑う。
描画のためにデータを加工する → コンポーネントの最上位で計算する
state を更新すると描画からやり直しになる
利用者の操作に反応する → イベントハンドラに書く
Effect が走る時点では「何が起きたか」が分からない
判断の仕方が示されている。
「なぜこのコードが動く必要があるのか」を問い、
コンポーネントが利用者に表示されたから 動くべきものだけを Effect に置く。
これは原則の 「なんのためか目的を考える」を、この場面に当てたもの。
🔹 4. コンポーネント間のデータ受け渡し (props)
親コンポーネントから子コンポーネントにデータを渡す。
function Child({ message }) {
return <h2>子コンポーネント: {message}</h2>;
}
function Parent() {
return (
<div>
<h1>親コンポーネント</h1>
<Child message="こんにちは!" />
</div>
);
}
export default Parent;🔹 5. グローバル状態管理 (useContext)
テーマをアプリ全体で共有する。
import { createContext, useContext, useState } from "react";
const ThemeContext = createContext();
function ThemeProvider({ children }) {
const [theme, setTheme] = useState("light");
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
{children}
</ThemeContext.Provider>
);
}
function ThemedButton() {
const { theme, setTheme } = useContext(ThemeContext);
return (
<button
style={{
background: theme === "light" ? "#fff" : "#333",
color: theme === "light" ? "#000" : "#fff",
}}
onClick={() => setTheme(theme === "light" ? "dark" : "light")}
>
{theme === "light" ? "ダークモードにする" : "ライトモードにする"}
</button>
);
}
function App() {
return (
<ThemeProvider>
<h1>テーマ切り替え</h1>
<ThemedButton />
</ThemeProvider>
);
}
export default App;🔹 6. ルーティング (React Router)
ページ遷移を実装する。
import { BrowserRouter as Router, Routes, Route, Link } from "react-router-dom";
function Home() {
return <h1>ホームページ</h1>;
}
function About() {
return <h1>このサイトについて</h1>;
}
function App() {
return (
<Router>
<nav>
<Link to="/">ホーム</Link> | <Link to="/about">このサイトについて</Link>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</Router>
);
}
export default App;Reactの基本フック一覧
| フック名 | 用途 |
|---|---|
| useState | 状態管理(コンポーネント内) |
| useEffect | 副作用の処理(データ取得・DOM操作) |
| useContext | グローバルな状態管理 |
| useReducer | useState よりも複雑な状態管理 |
| useRef | DOM要素や値の参照 |
| useMemo | 計算結果をキャッシュしてパフォーマンス最適化 |
| useCallback | 関数のメモ化 |
関連
- 言語・フレームワーク — この階層はバージョンに依存する
- React と Stimulus の使い分け — どちらを選ぶか
- ユーザー体験の目標 — ネットワークの滝は LCP に効く
- アクセシビリティ — 独自コンポーネントに名前・役割・値を与える義務
- 原則 — Effect を置くかの判断