- React
Too many re-rendersの原因と直し方|React
Too many re-renders. React limits the number of renders to prevent an infinite loop. は、コンポーネントを描画(レンダー)している最中に state を更新し、「描画 → 更新 → 描画 → 更新…」が止まらなくなったときのエラーです。 一番多い原因は、onClick に関数を渡すつもりで、呼び出してしまう書き間違いです。
<button onClick={handleClick()}>追加</button> // ✕ 描画のたびに handleClick を実行してしまう
<button onClick={handleClick}>追加</button> // ○ 関数を渡す
<button onClick={() => handleClick(id)}>追加</button> // ○ 引数を付けたいときはアロー関数で包む
確認環境:React 19.3.0、react-dom 19.3.0(jsdom 26 の上で createRoot で描画)(確認日 2026年10月11日)。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Too many re-rendersの原因と直し方|React」
再現:どの書き方でエラーになるか
確認環境で、描画の回数を数えながら試しました。
| 書き方 | 描画の回数 | 結果 |
|---|---|---|
onClick={setCount(count + 1)} |
52 回で停止 | Too many re-renders |
onClick={handleClick()}(中で setState) |
52 回で停止 | Too many re-renders |
onClick={() => handleClick()} |
1 回 | 正常 |
レンダーの中で、条件なしに setCount(1) |
52 回で停止 | Too many re-renders |
| レンダーの中で、条件付きで setState(前回の値と違うときだけ) | 2 回 | 正常 |
onClick={setCount(count + 1)} は、「クリックされたら実行する関数」ではなく、「描画中に今すぐ実行した結果」を onClick に渡しています。 実行するたびに state が変わって再描画され、また実行され…と続き、約 50 回で React が止めました。React の公式ドキュメントでも、この原因の多くはイベントハンドラーの書き間違い(() が付いている)だとされています。
レンダー中の setState が必要なとき
function List({ items }) {
const [prevLen, setPrevLen] = useState(null);
if (prevLen !== items.length) { // ← 条件があるので、2回目の描画で止まる
setPrevLen(items.length);
}
...
}
前回の値と比べる条件の中でだけ setState すると、2回の描画で落ち着きました。 公式ドキュメントでも、描画中に set を呼ぶなら必ず条件の中で、と説明されています(ただし、分かりにくいので、なるべく避ける書き方とされています)。
エラーにならない無限ループ:useEffect
useEffect の中の setState でも無限ループは起きますが、Too many re-renders にはなりませんでした。
| 書き方 | 300 ミリ秒の間の描画の回数 | 結果 |
|---|---|---|
useEffect(() => { setCount(count + 1); })(依存配列なし) |
2,470 回 | エラーで止まらず、Maximum update depth exceeded ... の警告(console.error)だけ |
useEffect(() => {...}, [opt])(opt は毎回作るオブジェクト) |
4,916 回 | 同上 |
useMemo で opt を作る |
2 回 | 正常 |
useEffect(() => {...}, []) |
2 回 | 正常(最初の1回だけ) |
Maximum update depth exceeded. This can happen when a component calls setState inside useEffect,
but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.
画面は動き続けたまま、裏で描画が数千回繰り返されました。 useEffect の中で API を呼んでいれば、その回数だけ呼ばれ続けます。コンソールの Maximum update depth exceeded の警告を見逃さないようにします。
オブジェクトを依存配列に入れると、毎回「変わった」とみなされる
const opt = { page: 1 }; // 描画のたびに新しいオブジェクト
useEffect(() => { fetchList(opt); setLoaded(x => x + 1); }, [opt]); // ✕ 毎回実行される
const opt = useMemo(() => ({ page: 1 }), []); // ○ 同じオブジェクトを使い回す
useEffect(() => { ... }, [page]); // ○ オブジェクトではなく、中の値を依存にする
中身が同じでも、毎回新しく作ったオブジェクトは「別のもの」として比べられます。 公式ドキュメントでも、コンポーネントの中で作るオブジェクトや関数を依存配列に入れると、必要以上に再実行される原因になるとされています。依存配列には、オブジェクトではなく page のような値を入れるか、オブジェクトを useEffect の中で作ります。
エラーの種類の見分け方
| 表示 | 起きている場所 | 主な原因 |
|---|---|---|
Too many re-renders(エラーで止まる) |
描画の最中 | onClick={f()}、条件なしの setState |
Maximum update depth exceeded(警告、動き続ける) |
useEffect | 依存配列なし、毎回変わる依存 |
確認の手順(チェックリスト)
| 順番 | 確認すること | 方法 |
|---|---|---|
| 1 | どちらの表示か | Too many re-renders か Maximum update depth か |
| 2 | イベントハンドラー | onClick={f()}・onChange={setX(...)} になっていないか |
| 3 | 描画の中の setState | 条件の中だけか |
| 4 | useEffect の依存配列 | 書いてあるか、毎回変わるもの(オブジェクト・関数)が無いか |
| 5 | 直す | 関数を渡す・アロー関数・useMemo・値を依存にする |
| 6 | 確かめる | コンソールのエラーのスタックで、どの set が呼ばれたか |
よくある質問
Q. 描画の回数を確かめる方法はありますか。 A. 確認環境では、コンポーネントの中で回数を数える変数を増やして確かめました。再描画の原因全体は、関連記事の「React再レンダリングの原因と確認方法|childrenで防ぐ書き方」で扱っています。
まとめ
- 描画の最中に state を更新し続けたエラー。約 50 回で React が止める
- 一番多いのは
onClick={handleClick()}。onClick={handleClick}か() => handleClick(id)に - 描画中の setState は、前回と違うときだけの条件の中で
- useEffect の無限ループは、エラーにならず数千回描画が続く。
Maximum update depth exceededの警告に注意 - 依存配列にはオブジェクトではなく値を。オブジェクトなら useMemo
参考・出典
確認日はいずれも 2026年10月11日です。
- React「useState」(Troubleshooting):https://react.dev/reference/react/useState
- React「useEffect」(Troubleshooting):https://react.dev/reference/react/useEffect
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Too many re-rendersの原因と直し方|React」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。