Reactの挙動がよくわからないときのメモ

カテゴリー:技術

頭おかしくなりそう

import { useEffect, useState } from "react";

const Example = () => {
  const [time, setTime] = useState(0);
  // const [nonE, setNonE] = useState(0);

  // 再レンダリング→このコンポーネントの関数がもう一度実行されていく
  // だから画面のように下の関数の数字は時間経過と共におかしな増え方をしていく
  // window.setInterval(() => {
  //   console.log("called!");
  //   setNonE((prev) => prev + 1);
  // }, 1000);
  // useEffectで第二引数を[]で空で渡すと初回第一引数は初回レンダリングしか実行されない
  useEffect(() => {
    console.log("useEffect is called");
    // これは非同期的
    // つまりこれが実行されることによって再レンダリングが発生している
    window.setInterval(() => {
      console.log("setTime");
      // レンダリングの予約、次レンダリング時に反映
      setTime((prev) => prev + 1);
    }, 1000);
  }, []);

  // こう書くとtimeが更新されるたびに中のものが呼び出される
  useEffect(() => {
    console.log("set localStorage");
    document.title = "counter" + time;
    window.localStorage.setItem("timeKey", time);
    localStorage.thisIsKey = time;
  }, [time]);
  // なぜ一秒遅れなのか
  // localValueはレンダリングされるたびに呼ばれる
  // 同期的に動いている。
  // つまりレンダリング時に呼び出される
  console.log("rendering and get localStorage");
  const localValue = localStorage.getItem("timeKey");
  return (
    <h3>
      <time>{time}</time>
      <span>秒経過</span>
      {/* <time>{nonE}</time> */}
      <p>This is get from localStorage</p>
      <p>{localValue}</p>
      <span>秒経過</span>
    </h3>
  );
};

export default Example;
  1. useEffect発火カウント開始 ここでは0
  2. localStorageの値を取得 ここではまだ0
  3. useEffect二つ目発火 まだ0
  4. useStateのsetは次レンダリング直前に反映されるここで1になるがこれが反映されるのは次のレンダリング時
  5. timeに1+したものをセット
  6. レンダリングされる 同時にlocalStorageの値取得 しかし、localStrageはまだ更新されていないので0
  7. useEffectは主要なレンダリングがすんでから実行。ここでやっとlocalStorage更新
  8. ここで表示されているのはtimeとlocalStorageだから一秒づつ遅れている!!!