3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【React】レンダリング無限ループが発生【Class Component】

Last updated at Posted at 2021-02-08

現象

背景

ReactのClassComponentでこのようなコードを書いていました。
※簡略化されています

export class Header extends React.Component {
  static contextType = ThemeContext;

  render() {
    const { tab, setTab } = this.props;
    const [theme, toggleTheme] = this.context;

    return (
      <Container>
        <HeaderUl>
          <HeaderLi onClick={() => setTab('list')}>リスト</HeaderLi>
        </HeaderUl>
        <HeaderButton onClick={toggleTheme()}>テーマの変更</HeaderButton>
      </Container>
    )
  }
}

エラー内容

ビルドを走らせたところ発生したエラーがこちら。

Uncaught Invariant Violation: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.

適当にGoogle翻訳に突っ込んでみると、
「最大更新深度を超えた」
「setStateを繰り返し呼び出す場合に発生」
「ネストされた更新の数を制限して無限ループを防ぐ」
と言う意味ありげな内容が含まれていることが分かりました。

原因

どうやらReact.ComponentはsetStateが呼ばれた後に再レンダリングするサイクルがデフォルトになっているようで、

  1. renderの実行
  2. toggleTheme()の実行
  3. setStateの実行
  4. 1に戻る

と無限ループに入ってしまっていたようでした。

解決策

onClickに関数を渡すように記述を変更することで解決できました。

変更前

<HeaderButton onClick={toggleTheme()}>テーマの変更</HeaderButton>

変更後

<HeaderButton onClick={() => toggleTheme()}>テーマの変更</HeaderButton>

参考

何故「Uncaught Invariant Violation: Maximum update depth exceeded.」というエラーが出るのかわかりません。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?