LoginSignup
1
0

useEffectは実行されずuseLayoutEffectのみ実行されて困った話

Last updated at Posted at 2024-05-06

useEffectとuseLayoutEffectの今ままでの認識ついて

useEffectとuseLayoutEffectの詳しい説明は省きますが、ざっくり以下のように考えていて
実行タイミングが違うだけで片方のみ実行されるタイミングがあるとは思っていませんでした。
useEffect:ブラウザが画面を描画した後に実行される
useLayoutEffect:ブラウザが画面を描画する前に実行される

詳しい説明用URL

useEffect公式記事
useLayoutEffect公式記事
ReactCompleteGuide(useEffect)
ReactLifecycle

調査結果

調べてみたところSuspence時にはuseEffectは実行されず、useLayoutEffectは実行されるようでした。

App.tsx
import { Suspense, useState } from "react";
import { TestComponent } from "./TestComponet";
import { Footer } from "./Footer";

function App() {
  const [isSuspence, SetIsSuspence] = useState(false);
  return (
    <>
      <Suspense fallback="loading...">
        <TestComponent isSuspence={isSuspence} />
      </Suspense>
      <br />
      <Footer isSuspence={isSuspence} setIsSuspence={SetIsSuspence} />
    </>
  );
}

export default App;
TestComponent.tsx
import { useEffect, useLayoutEffect } from "react";

function sleep(ms: number): Promise<void> {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

export function TestComponent({ isSuspence }: { isSuspence: boolean }) {
  useEffect(() => {
    console.log("useEffect:callback");
    return () => {
      console.log("useEffect:clean up");
    };
  }, []);

  useLayoutEffect(() => {
    console.log("useLayoutEffect:callback");
    return () => {
      console.log("useLayoutEffect:clean up");
    };
  }, []);

  if (isSuspence) {
    throw sleep(3000);
  } else {
    return <button>button</button>;
  }
}
Footer.tsx
import { Dispatch, SetStateAction } from "react";

export function Footer({
  isSuspence,
  setIsSuspence,
}: {
  isSuspence: boolean;
  setIsSuspence: Dispatch<SetStateAction<boolean>>;
}) {
  const handleClick = () => {
    setIsSuspence(!isSuspence);
  };
  return (
    <button onClick={handleClick}>
      {'Suspenceを' + (!isSuspence) + ''}
    </button>
  );
}

React-App-Effect-Test.gif

よく調べてみると公式サイトに記載があった

useEffectとuseLayoutEffectの記事では見つけられませんでしたが、
Suspenceの記事に記載がありました。

Suspense公式記事

感想

考えてみたらコンポーネント描画前にuseLayoutEffectが実行されるなら
Suspenceでその要素がなくなったら、useLayoutEffect実行されそうって
考えられるし、公式記事もあったし、もしかしてこれに躓いてたの僕だけかも?

最後に

同じ現象に陥った人の助けになればと思います。
ここまで読んでいただきありがとうございました。

1
0
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
1
0