created: 2020-11-05T06:07:42.000Z

React.SuspenseとsetTimeoutで最小限の非同期コンポーネントをつくる

こんなコードで1秒後に helloworld と表示できるコンポーネントが作れる

// 「1秒以内はPromiseがthrowされて、1秒後にはundefinedが返ってくる関数」を返す関数
const delay = () => {
  let isTimeout = false;
  // 1秒後にisTimeoutがTrueになる
  const promise = new Promise(resolve => setTimeout(() => resolve(), 1000));
  promise.then(() => (isTimeout = true));

  return () => {
    if (isTimeout) {
      return;
    } else {
      // 1秒まではいつ呼んでもPromiseがthrowされる
      // Promiseがthrowされる限りSuspenseはfallbackを表示する
      throw promise;
    }
  };
};
let f;
const Trigger = () => {
  // このあと何回Trigger関数が呼ばれても1秒間はPromiseがthrowされる
  f = f || delay();
  f();
  // 1秒後からTrigger関数は正常に終了して普通のコンポーネントが返ってくるようになる
  return <p>hello world</p>;
};
const DelayedComp = () => {
  return (
    // throwされたPromiseはReact.Suspenseがcatchしてfallbackを表示してくれる
    <React.Suspense fallback={<p>loading...</p>}>
      <Trigger />
    </React.Suspense>
  );
};
ReactDOMServer.renderToString(<DelayedComp />);

参考

失敗から学ぶユーザインタフェース 世界はBADUI(バッド・ユーアイ)であふれている
[ad] 失敗から学ぶユーザインタフェース 世界はBADUI(バッド・ユーアイ)であふれている
中村 聡史 (大型本)