Skip to content

Commit

Permalink
Add note to docs on layout useLoaderData restriction (#8958)
Browse files Browse the repository at this point in the history
Co-authored-by: houmark <lars@houmark.com>
  • Loading branch information
brophdawg11 and houmark committed Mar 4, 2024
1 parent 34fb87c commit 0bdbef7
Showing 1 changed file with 50 additions and 0 deletions.
50 changes: 50 additions & 0 deletions docs/file-conventions/root.md
Expand Up @@ -146,6 +146,56 @@ export function ErrorBoundary() {
}
```

**A note on `useLoaderData`in the `Layout` Component**

`useLoaderData` is not permitted to be used in `ErrorBoundary` components because it is intended for the happy-path route rendering, and its typings have a built-in assumption that the `loader` ran successfully and returned something. That assumption doesn't hold in an `ErrorBoundary` because it could have been the `loader` that threw and triggered the boundary! In order to access loader data in `ErrorBoundary`'s, you can use `useRouteLoaderData` which accounts for the loader data potentially being `undefined`.

Because your `Layout` component is used in both success and error flows, this same restriction holds. If you need to fork logic in your `Layout` depending on if it was a successful request or not, you can use `useRouteLoaderData("root")` and `useRouteError()`:

```tsx filename="app/root.tsx" lines=[6-7,19-29,32-34]
export function Layout({
children,
}: {
children: React.ReactNode;
}) {
const data = useRouteLoaderData("root");
const error = useRouteError();

return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1"
/>
<Meta />
<Links />
<style
dangerouslySetInnerHTML={{
__html: `
:root {
--themeVar: ${
data?.themeVar || defaultThemeVar
}
}
`,
}}
/>
</head>
<body>
{data ? (
<Analytics token={data.analyticsToken} />
) : null}
{children}
<ScrollRestoration />
<Scripts />
</body>
</html>
);
}
```

See also:

- [`<Meta>`][meta-component]
Expand Down

0 comments on commit 0bdbef7

Please sign in to comment.