記事検索

検索ワードを入力してください。
Sky Tech Blog
【初学者向け】Reactで​起きる​無限レンダリング

【初学者向け】Reactで​起きる​無限レンダリング

React初学者が陥りやすい「無限レンダリング」問題について、その原因と対策を解説。useStateによる状態更新やuseEffectの依存配列の誤りが引き起こす無限ループの具体例と、useCallbackなどを用いた解決策を紹介します。

はじめに

Reactを学習し始めたばかりの方が陥りやすい問題の一つに「無限レンダリング(無限表示)」があります。
この記事では、無限レンダリングが発生する原因やその対策について解説します。

無限レンダリングとは?

無限レンダリングとは、Reactコンポーネントが何度も再レンダリングされ続ける現象です。
これが発生すると、アプリケーションのパフォーマンスが著しく低下し、最悪の場合、ブラウザがクラッシュすることもあります。

無限レンダリングが​発生する​原因

無限レンダリングが発生する主な原因は以下のとおりです

  1. 状態の更新が原因
  2. 依存配列の誤り

一つずつ見てみましょう。

1.状態の​更新が​原因

useStateフックを使用して状態を管理する際に、状態の更新がレンダリングのたびに行われると無限ループが発生します。
例えば、以下のようなコードです。

import React, { useState } from 'react';

const ExComponentSky = () => {
  const [count, setCount] = useState(0);

  setCount(count + 1); // これが無限レンダリングの原因

  return <div>{count}</div>;
};

上記は、ExComponentSkyが作成されるとレンダリングが発生 ⇒
setCountにより状態が更新(再レンダリングされる) ⇒
ExComponentSkyでレンダリングが発生したので再びsetCountが実行され状態が更新(再再レンダリング) ⇒
・・・・・というような形です。

この例はわかりやすいので陥ることも少ないかと思いますが、もう少し複雑な親子コンポーネントになると注意が必要です。

2.依存配列の​誤り

親コンポーネントで状態管理しているフックを子コンポーネントに渡す例を考えてみます。

★親コンポーネント★
const ParentComponent = () => {
  const [count, setCount] = useState(0);

  const increment = () => {
    setCount(prevCount => prevCount + 1);
  };

  return (
    <div>
      <h1>回数: {count}</h1>
      
    </div>
  );
};
★子コンポーネント★
const ChildComponent = ({ increment }) => {
  useEffect(() => {
    increment();
  }, [increment]);

  return (
    <div>
      <button onClick={increment}>増やす!</button>
    </div>
  );
};

この例では以下のように処理が行われます。

  1. 親コンポーネントが初回レンダリングされ、increment関数が生成されます。
  2. 子コンポーネントがレンダリングされ、useEffectが実行されます。
  3. useEffect内でincrement関数が呼び出され、countが更新されます。
  4. 親コンポーネントが再レンダリングされ、新しいincrement関数が生成されます。
  5. 子コンポーネントが再レンダリングされ、useEffectが再度実行されます。
  6. このサイクルが無限に続き、無限レンダリングが発生します。

上記は極端な例ですが、複数の関数を経由していたり、親子関係が深いものになればなるほど思わぬ事故を引き起こします。

対策としては、useEffectの依存配列を適切に設定するか、useCallbackというものを使用して、increment関数オブジェクトが再作成されないようにすることが考えられます。
useCallbackは上記の4番が行われないようにすることで無限レンダリングを止める機能を持ちます。

★親コンポーネントの修正例(useCallback)★
const ParentComponent = () => {
  const [count, setCount] = useState(0);

  const increment = useCallback(() => {
    setCount(prevCount => prevCount + 1);
  }, []);

  return (
    <div>
      <h1>回数: {count}</h1>
      
    </div>
  );
};

もしくは、

★子コンポーネントの修正例(依存配列の見直し)★
const ChildComponent = ({ increment }) => {
 useEffect(() => {
   increment();
 }, []);// 依存配列を空にすると、初回レンダリング時のみ実行されます

 return (
   <div>
     <button onClick={increment}>増やす!</button>
   </div>
 );
};

まとめ

ReactとTypeScriptを使い始めたばかりの初学者が陥りやすい無限レンダリングの原因と対策について簡単に解説しました。
無限レンダリングを防ぐには、状態の更新や依存配列の設定に注意することが大切です。
これらのポイントを押さえて、React開発を楽しんでみてはいかがでしょうか。


\シェアをお願いします!/
  • X
  • Facebook
  • LINE
キャリア採用募集中!

入社後にスキルアップを目指す若手の方も、ご自身の経験を幅広いフィールドで生かしたいベテランの方も、お一人おひとりの経験に応じたキャリア採用を行っています。

Sky株式会社のソフトウェア開発や製品、採用に関するお問い合わせについては、下記のリンクをご確認ください。
お問い合わせ
ホーム