💿

Remix で preload パターンを実装する

2024/05/04に公開

https://zenn.dev/you_5805/articles/rsc-preload-pattern

↑の記事で Next.js での preloadパターンの実装について紹介されていたので、それのRemix版です。

https://remix.run/

deferを用いた実装

Remixのloaderdeferを使用することでストリーミング/遅延レスポンスを返却することができます。

https://remix.run/docs/en/main/route/loader
https://remix.run/docs/en/main/utils/defer

実装例は以下の通りです。

export const loader = async () => {
  const aStillRunningPromise = loadSlowDataAsync();

  const isAuthenticated = await getIsAuthenticated();
  if (!isAuthenticated) {
    redirect('/login');
  }

  return defer({
    slowPromise: aStillRunningPromise,
  });
}

export default function Page() {
  const { slowPromise } = useLoaderData<typeof loader>();

  return (
    <Suspense fallback={<div>Loading...</div>}>
      <Await resolve={slowPromise}>
        {(resolved) => <p>{resolved.title}</p>}
      </Await>
    </Suspense>
  );
}

use API を使うパターン

slowPromiseはPromiseなので勘のいい方ならお気づきかもしれませんが、こちらも React の use を使うことができます。

https://react.dev/reference/react/use

export const loader = async () => {
  const aStillRunningPromise = loadSlowDataAsync();

  const isAuthenticated = await getIsAuthenticated();
  if (!isAuthenticated) {
    redirect('/login');
  }

  return defer({
    slowPromise: aStillRunningPromise,
  });
}

export default function Page() {
  const { slowPromise } = useLoaderData<typeof loader>();
  const resolved = use(slowPromise);

  return (
    <p>{resolved.title}</p>
  );
}

<Suspense><Await>でラップする必要がなくなったのでHTMLがスッキリしましたね。

というわけで

Remix版でした。

Discussion