現象
背景
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が呼ばれた後に再レンダリングするサイクルがデフォルトになっているようで、
- renderの実行
- toggleTheme()の実行
- setStateの実行
- 1に戻る
と無限ループに入ってしまっていたようでした。
解決策
onClickに関数を渡すように記述を変更することで解決できました。
変更前
<HeaderButton onClick={toggleTheme()}>テーマの変更</HeaderButton>
変更後
<HeaderButton onClick={() => toggleTheme()}>テーマの変更</HeaderButton>
参考
何故「Uncaught Invariant Violation: Maximum update depth exceeded.」というエラーが出るのかわかりません。