メインコンテンツまでスキップ

第56章:「副作用」ってなに?

(表示以外の仕事。通信とか、タイマーとか)


🎯 この章のゴール

この章では、

  • 「**副作用(ふくさよう)**ってなに?」
  • いつもの React の仕事と、副作用の仕事はどう違うの?」
  • 「どんな処理が副作用になるの?」

を、ふんわりイメージできるようになることがゴールです ✨ コードはまだ軽めにして、考え方の整理メインでいきます。

次の第57章から、実際に useEffect を触っていく予定です 💪


1️⃣ React の仕事はざっくり「2種類」あるよ 🧠

まず、React がやっている仕事をざっくり分けると、こうなります:

  1. 画面に何を表示するか計算する仕事(=レンダリング)
  2. 「外の世界」とやりとりする仕事(=副作用)

① レンダリングの仕事(メインの仕事)🖼

  • 入力propsstate
  • 出力:JSX(=最終的には HTML に変わる)

同じ propsstate なら、必ず同じ JSX を返すのが理想です。 この状態を「純粋(ピュア)」って呼んだりします。

② 副作用の仕事(おまけじゃないけど、外回りの仕事)📞

アプリは「表示」だけじゃなくて、こんなこともしたいですよね:

  • サーバーからデータを取ってくる 📡
  • setIntervalsetTimeout でタイマーを動かす ⏰
  • document.title(タブのタイトル)を書き換える 🪄
  • スクロール位置を変えたり、特定の要素にフォーカスを当てる 🎯
  • localStorage にデータを保存する 💾
  • 分析ツールやチャットウィジェットと連携する 📊💬

こういう 「外の世界」に影響を与える処理 を まとめて 「副作用(side effect)」 と呼びます。


2️⃣ ふつうの JavaScript で考える「副作用」🧪

まずは React を忘れて、ふつうの関数で考えてみましょう。

🔹 副作用なしの関数(ピュア)

function add(a: number, b: number): number {
return a + b;
}

const result = add(2, 3); // いつ呼んでも 5
  • 外の変数を書き換えたりしない
  • コンソールに何か出したりしない
  • ネット通信もしない

👉 「入力が同じなら、必ず出力も同じ」な関数です。

🔸 副作用ありの関数(インピュア)

let total = 0;

function addAndLog(a: number, b: number): number {
const result = a + b;
total += result; // 外の変数を書き換えている
console.log(total); // コンソールに出力している
return result;
}
  • グローバル変数 total を変更している
  • console.log で「外の世界」になにかを出力している

こういう 「戻り値以外にも、何かが変わる」 のが副作用です ⚠️


3️⃣ React コンポーネントに戻すとどうなる?🧩

React のコンポーネントも、できるだけ「ピュア」にしたい んです。

function Hello({ name }: { name: string }) {
return <h1>Hello, {name}</h1>;
}

このコンポーネントは、

  • name"Miku" なら、いつ呼んでも Hello, Miku ✨ を表示
  • 余計なことは一切しない(ネット通信とか、localStorage 書き込みとか)

なので「表示の計算だけしている、ピュアなコンポーネント」です ✅


4️⃣ これは「副作用」っぽい書き方(やっちゃダメな例)🙅‍♀️

コンポーネントの「本体」の中で、こんなことをすると危険です👇

function BadComponent() {
// ❌ コンポーネントの本体で副作用をやっちゃってる例
document.title = "Bad Example"; // タブタイトルを書き換え
console.log("レンダリングされました"); // ログ出力

setInterval(() => {
console.log("1秒ごとにログ"); // タイマーでログ(しかも毎回増える)
}, 1000);

return <div>よくない書き方です… 🥲</div>;
}

なにがダメかというと…

  • React は状況によって、同じコンポーネントを何回も呼ぶことがあります
  • そのたびに setInterval が増えて、タイマーがどんどん増殖💣
  • ログが大量に出たり、通信が何度も走ったりするかも…

React 19 ではレンダリングがもっと賢く・柔軟になっているので、 「いつ何回呼ばれても安全」な書き方をする必要があります。

👉 そのために、副作用は専用の場所にまとめようね、という話になって 👉 そこで登場するのが useEffect です(次の章で登場!🎉)


5️⃣ 副作用と「レンダリング」のイメージを図で見てみよう 🧠✨

React の中で何が起きてるか、ざっくりイメージ図です 👇

  • 上のルート:「表示の計算」(レンダリング)
  • 下のルート:「副作用」(外の世界とのお仕事)

この2つを 頭の中で分けて考えられるようになる と、 React のコードがすごくスッキリ見えるようになります 👀💡


6️⃣ どこからが「副作用」?具体例リスト 📋

React 的に「副作用っぽいよ〜」とみなされる代表メンバーたちです:

✅ 典型的な「副作用」

  • fetchaxios などで API からデータを取ってくる → ネットワークとやりとりしているから 🌐
  • setInterval, setTimeout などの タイマーをセット → 時間が経つとまた何か起きる ⏰
  • document.titledocument.body を直接いじる → React の外にある DOM をいじっている 🧱
  • window.addEventListener('resize', ...) などで イベントリスナーを登録 → ブラウザ全体のイベントと接続している
  • localStorage.setItem(...) でデータ保存 → ブラウザに永続保存している 💾
  • 分析ツール(Analytics)にイベントを送る → 別のサービスと通信している 📊

🧮 逆に「副作用じゃない」もの

  • map, filter で配列を加工して 表示用のデータを作る
  • useState の値をもとに 計算だけする
  • JSX の中で {count * 2} みたいに表示用の値を計算する

こういうのは全部「レンダリングのための計算」です ✨ 外の世界は変えていないので、副作用ではありません。


7️⃣ React 19 時代の「副作用」の立ち位置 💫

React 19 では、

  • データ取得用の use(Promise)
  • フォーム用の Actions (<form action={...}>, useActionState など)

みたいな 「特定の用途に特化した仕組み」 が増えています。

でも考え方としては、

React の外にある世界とやりとりするときは、副作用の話になる

というのは変わりません ✨

  • ネットワーク
  • DOM(document, window
  • ブラウザのストレージ
  • 外部サービス(チャット、分析ツール、地図ウィジェット etc.)

こういうものは 全部「外の世界」 です 🌎


8️⃣ ミニクイズ:「これは副作用?」ゲーム 🎮

ちょっとだけ頭の中で答えてみてください 👀

Q1. 副作用? or NOT?

const doubled = count * 2; と計算して JSX に {doubled} を表示する。

  • 👉 副作用じゃない → ただの計算。外の世界は何も変えていない。

Q2. 副作用? or NOT?

ボタンを押したときに alert('送信しました!') を出す。

  • 👉 副作用 → 画面にポップアップを出しているので、「React の外の世界」を動かしている。

Q3. 副作用? or NOT?

入力されたテキストを localStorage に保存する。

localStorage.setItem("memo", text);
  • 👉 副作用 → ブラウザにデータを書き込んでいる(永続保存)ので、まさに副作用。

Q4. 副作用? or NOT?

useStatesetCount(count + 1) する。

  • これはちょっとグレーゾーンに見えますが、React 的には 「React の管理している state を更新しているだけ」 と考えて OK です 💡
  • ここでは「外の世界」じゃなくて「React の中の世界」の話なので、 「副作用」ではなく、普通の状態更新 として扱います。

(細かい理屈は大人の事情なので、今は「そういうものか〜」で大丈夫です🫶)


9️⃣ この章のまとめ ✨

この章で覚えておきたいのは、この3つです👇

  1. React の仕事は「表示の計算」と「副作用」に分けて考える
  2. 副作用 = 外の世界(API / タイマー / DOM / localStorage など)に影響を与える処理
  3. コンポーネント本体はできるだけ「ピュア」にして、 副作用は専用の仕組み(useEffect など)にまとめる

🔮 次の第57章への予告:useEffect 登場!

次の章ではいよいよ、

  • 「副作用を いつ 実行するか」
  • どのタイミング でやれば安全なのか」
  • そのためのフック、useEffect の基本

を学んでいきます 💻✨

「画面の表示が終わったら、これやっといて〜」 と React にお願いする方法です 🧚‍♀️

ここまで読めていれば、もうすでに 「副作用ってなに?」の壁はほぼクリア してます 🎉

ゆっくりで大丈夫なので、何度か読み返して 「外の世界とやりとりする処理=副作用」というイメージだけ しっかり頭に置いておいてくださいね 🌸