無限ループになったコード例
useStateで定義した変数をuseEffectで監視する場合に起こった。
import React, { useState, useEffect } from "react";
export const CountUpComponent = () => {
const [count, setCount] = useState(0);
useEffect(() => {
setCount(Math.random());
}, [count]);
return <div>{count}</div>;
};
export default CountUpComponent;
解説
現象 | countの具体例 |
---|---|
最初のレンダーの際、countは初期値である 0 でレンダーされる。 | 0 |
その後、useEffectによりcountの値が変化する。 | 5 |
値が変化したので、コンポーネントの再レンダーが走る。 | 5 |
再レンダー後、再度useEffectが呼ばれてcountの値が変化する。 | 2 |
値が変化したので、コンポーネントの再レンダーが走る。 | 2 |
再レンダー後、再度useEffectが呼ばれてcountの値が変化する。 | 9 |
・ | ・ |
・ | ・ |
・ | ・ |
というように、無限ループが発生してしまう。
useStateは、値が変われば再レンダーする特性があることをしっかり理解しておこう。
解決策
①監視を止める(空配列にする)
import React, { useState, useEffect } from "react";
export const CountUpComponent = () => {
const [count, setCount] = useState(0);
useEffect(() => {
setCount(Math.random());
}, []); //←countを削除して空配列にする
return <div>{count}</div>;
};
export default CountUpComponent;
②useStateを使わない
import React, { useEffect } from "react";
export const CountUpComponent = () => {
let count = 0;
count = Math.random();
return <div>{count}</div>;
};
export default CountUpComponent;