import React, { useEffect, useState } from "react";
export function App() {
const [count, setCount] = useState(0);
useEffect(() => {
const timer = setInterval(() => {
setCount((prevCount) => prevCount + 1);
}, 1000);
return () => {
clearInterval(timer);
};
}, []); // 第二引数が空の配列
return <div>{count}</div>;
}
index.jsx内などでAppが呼ばれたときに
まずuseStateが定義される、countの初期値0
useEffectの第二引数は空配列[]なので初回のレンダリング時にのみ実行される
const timer = setInterval( () => {
setCount((prevCount) => prevCount + 1);
}, 1000);
定数timerの中に実行したsetIntervalのアドレスを格納する。
このときにtimerを定義してアドレスを格納させておくのはあとでsetIntervalを止める際にsetIntervalを直で実行してしまうと指定できなくなってしまうため。
setIntervalは非同期処理の関数のため、バックグラウンドで実行されるため処理自体は次にそのまま進んでいく。
return () => {
clearInterval(timer);
};
useEffect内に記述されたreturnは最初のレンダリング時には実行されず、useEffectが記述されているコンポーネント、つまりこの場合だとApp()が画面から表示されなくなる(アンマウント)ときにアンマウントの直前にreturnのあとに記述した処理が走るようになっている。(これはもうuseEffectの仕組みだと思われる)
このときreturnで実行する処理は動かし続けているtimerを止めるという処理。ページ変わるしもういらないよねということだと思う。非同期処理なので明示的に止めたり消したりしないとずっと動き続けてしまう。
ー 流れ ー
ルーティングの遷移などの命令がきてどうやら画面からコンポーネントが消えそう
↓
useEffectのreturnに記述した処理が実行される
↓
画面からコンポーネントが消える
みたいなことっぽい?
バックグラウンド処理のsetIntervalでは
1秒ごとにsetCountを実行してcountを+1し続けているので
1秒ごとにAppコンポーネントが最レンダリングされ続けているという状況。