#How to work with async handle function

1 messages · Page 1 of 1 (latest)

somber mantle
#

Hi everyone! I'm trying to implement breadcrumbs in my app so decided to use handle with useMatch to implement it so that I only have to specify the pages for the Breadcrumbs component in the each route and render the component only in my root component. However, I want to be able to fetch some data in my breadcrumbs handle function. This doesn't work currently because the component gets passed a promise instead of the pages array. Here's how I use handle in my route:

export const handle = {
  async breadcrumbs(match: RouteMatch) {
    const {
      params: { courseId },
    } = match;
    invariant(courseId, "Course ID is required");
    const course = await getCourse(courseId);

    if (!course) {
      throw new Response("Not Found", { status: 404 });
    }

    return [
      {
        name: course.title,
        href: match.pathname,
        current: true,
      },
    ];
  },
};

And here's how I use it in my root component:

export default function App() {
  const matches = useMatches();

  const match = matches.find(
    (match) => match.handle && match.handle?.breadcrumbs
  );

  return (
    <html lang="en" className="h-full">
      <head>
        <meta charSet="utf-8" />
        <meta name="viewport" content="width=device-width,initial-scale=1" />
        <Meta />
        <Links />
      </head>
      <body className="h-full">
        {match && <Breadcrumbs pages={match.handle?.breadcrumbs(match)} />}
        <Outlet />
        <ScrollRestoration />
        <Scripts />
        <LiveReload />
      </body>
    </html>
  );
}

So my question is how can I make an async handle function work. Or if that's not possible, can I use data from the loader in the handle function? I've tried that but it didn't work. Any help would be appreciated!

spare cargo
#

why not fetch the data in the loader function and then use it in handle?

astral lagoon
#

it looks like you're expecting your breadcrumbs function to work like a loader (server-side), but this will be called in a component so it runs both server and client side

I recommend you to fetch the course data (or throw a 404) in the loader of the route exporting the handle, then when you want to render the breadcrumbs pass match.data to let the breadcrumbs function (which should be a component) access the loader data