side-effect|副作用の検出とレビュー時の着眼点

概要

side-effect(副作用)とは、関数や処理が外部状態に影響を与えることを指します。
レビューでは、意図せぬ副作用の混入がないかをチェックすることが非常に重要です。
一見正しく見えるコードにも、予期せぬデータ破壊やパフォーマンス劣化の原因が潜んでいます。

「この処理、ほかのものに影響してない?」という問いが副作用のチェックの出発点です。

よくある副作用の例

ケース 内容
グローバル変数の書き換え 他の処理に影響を与える可能性がある
DOMの直接操作(Reactなどで) 仮想DOMの同期が崩れる
ストアやステートの外部更新 予期せぬ再レンダリング・データ競合の元
ネットワークやログの発火 条件次第で無限リクエストや重複送信の温床になる
// 副作用のある例
let counter = 0;
function increment() {
  counter++; // グローバルな状態を変えている
}

副作用のない関数(pure function)との比較

// 副作用のない関数(pure)
function add(a: number, b: number): number {
  return a + b;
}
  • 副作用がない=同じ入力→同じ出力
  • 内部状態や外部依存がない=テストしやすい/壊れにくい

「関数が何かを変えるのではなく、何かを返すだけ」という構造が保てているかを確認します。

レビューでの着眼点

  • この関数、呼び出すたびに同じ結果を返すか?
  • どこかの状態を変えていないか?(DOM, store, localStorageなど)
  • イベントハンドラやhookの中で影響範囲が予測可能か?
  • 実装者が副作用を意図しているか?説明できるか?
Reviewer: このuseEffect、依存配列なしで副作用走ってませんか?
Author: あ、初回実行のみにしたかったので配列追加します。

チームでの副作用管理ルール

  • グローバルな副作用(イベントリスナー、window書き換えなど)は必ずコメントで明示
  • hook内の副作用処理はユーティリティに切り出しておく
  • 「副作用を意図的に入れる」際はレビュアーとの認識を揃える
// NG: 不明確な副作用
useEffect(() => {
  localStorage.setItem("x", "y");
}, []);
// OK: コメントと分離で副作用を明示
useEffect(() => {
  // 初回だけ設定(仕様による)
  persistUserPreference("theme", "dark");
}, []);

関連用語

  • reusability:副作用の少ない関数ほど再利用しやすい
  • responsibility:副作用の責任を誰が持つか明確にする
  • readability:副作用が明示されているかどうかは読みやすさに影響する

実務視点まとめ

副作用は「気づきにくいバグの温床」です。コードの外に影響を及ぼす処理は、意図的であるか/説明できるか/予測可能かという観点でレビューすることが、安全で堅牢なコードベースを支えます。