Skip to content

Commit

Permalink
remove the usage of useRootLoaderData everywhere and the usage of use…
Browse files Browse the repository at this point in the history
…LoaderData from ErrorBoundary
  • Loading branch information
michenly committed Jun 5, 2024
1 parent ea1db72 commit d4f92d4
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 82 deletions.
6 changes: 3 additions & 3 deletions app/components/CountrySelector.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {useFetcher, useLocation, useMatches} from '@remix-run/react';
import {useFetcher, useLocation, useRouteLoaderData} from '@remix-run/react';
import {useCallback, useEffect, useRef} from 'react';
import {useInView} from 'react-intersection-observer';
import clsx from 'clsx';
Expand All @@ -10,12 +10,12 @@ import {Heading} from '~/components/Text';
import {IconCheck} from '~/components/Icon';
import type {Localizations, Locale} from '~/lib/type';
import {DEFAULT_LOCALE} from '~/lib/utils';
import {useRootLoaderData} from '~/hooks/useRootLoaderData';
import type {RootLoader} from '~/root';

export function CountrySelector() {
const fetcher = useFetcher();
const closeRef = useRef<HTMLDetailsElement>(null);
const rootData = useRootLoaderData();
const rootData = useRouteLoaderData<RootLoader>('root');
const selectedLocale = rootData?.selectedLocale ?? DEFAULT_LOCALE;
const {pathname, search} = useLocation();
const pathWithoutLocale = `${pathname.replace(
Expand Down
5 changes: 3 additions & 2 deletions app/components/Link.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import {
NavLink as RemixNavLink,
type NavLinkProps as RemixNavLinkProps,
type LinkProps as RemixLinkProps,
useRouteLoaderData,
} from '@remix-run/react';

import {useRootLoaderData} from '~/hooks/useRootLoaderData';
import type {RootLoader} from '~/root';

type LinkProps = Omit<RemixLinkProps, 'className'> & {
className?: RemixNavLinkProps['className'] | RemixLinkProps['className'];
Expand All @@ -28,7 +29,7 @@ type LinkProps = Omit<RemixLinkProps, 'className'> & {
*/
export function Link(props: LinkProps) {
const {to, className, ...resOfProps} = props;
const rootData = useRootLoaderData();
const rootData = useRouteLoaderData<RootLoader>('root');
const selectedLocale = rootData?.selectedLocale;

let toWithLocale = to;
Expand Down
14 changes: 8 additions & 6 deletions app/components/Layout.tsx → app/components/PageLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {useParams, Form, Await} from '@remix-run/react';
import {useParams, Form, Await, useRouteLoaderData} from '@remix-run/react';
import useWindowScroll from 'react-use/esm/useWindowScroll';
import {Disclosure} from '@headlessui/react';
import {Suspense, useEffect, useMemo} from 'react';
Expand Down Expand Up @@ -27,7 +27,7 @@ import {
} from '~/lib/utils';
import {useIsHydrated} from '~/hooks/useIsHydrated';
import {useCartFetchers} from '~/hooks/useCartFetchers';
import {useRootLoaderData} from '~/hooks/useRootLoaderData';
import type {RootLoader} from '~/root';

type LayoutProps = {
children: React.ReactNode;
Expand All @@ -37,7 +37,7 @@ type LayoutProps = {
};
};

export function Layout({children, layout}: LayoutProps) {
export function PageLayout({children, layout}: LayoutProps) {
const {headerMenu, footerMenu} = layout || {};
return (
<>
Expand Down Expand Up @@ -105,7 +105,8 @@ function Header({title, menu}: {title: string; menu?: EnhancedMenu}) {
}

function CartDrawer({isOpen, onClose}: {isOpen: boolean; onClose: () => void}) {
const rootData = useRootLoaderData();
const rootData = useRouteLoaderData<RootLoader>('root');
if (!rootData) return null;

return (
<Drawer open={isOpen} onClose={onClose} heading="Cart" openFrom="right">
Expand Down Expand Up @@ -321,7 +322,7 @@ function DesktopHeader({
}

function AccountLink({className}: {className?: string}) {
const rootData = useRootLoaderData();
const rootData = useRouteLoaderData<RootLoader>('root');
const isLoggedIn = rootData?.isLoggedIn;

return (
Expand All @@ -342,7 +343,8 @@ function CartCount({
isHome: boolean;
openCart: () => void;
}) {
const rootData = useRootLoaderData();
const rootData = useRouteLoaderData<RootLoader>('root');
if (!rootData) return null;

return (
<Suspense fallback={<Badge count={0} dark={isHome} openCart={openCart} />}>
Expand Down
12 changes: 0 additions & 12 deletions app/hooks/useRootLoaderData.tsx

This file was deleted.

8 changes: 4 additions & 4 deletions app/lib/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {useLocation, useMatches} from '@remix-run/react';
import {useLocation, useRouteLoaderData} from '@remix-run/react';
import type {MoneyV2} from '@shopify/hydrogen/storefront-api-types';
import type {FulfillmentStatus} from '@shopify/hydrogen/customer-account-api-types';
import typographicBase from 'typographic-base';
Expand All @@ -8,7 +8,7 @@ import type {
MenuFragment,
ParentMenuItemFragment,
} from 'storefrontapi.generated';
import {useRootLoaderData} from '~/hooks/useRootLoaderData';
import type {RootLoader} from '~/root';
import {countries} from '~/data/countries';

import type {I18nLocale} from './type';
Expand Down Expand Up @@ -270,7 +270,7 @@ export function getLocaleFromRequest(request: Request): I18nLocale {
}

export function usePrefixPathWithLocale(path: string) {
const rootData = useRootLoaderData();
const rootData = useRouteLoaderData<RootLoader>('root');
const selectedLocale = rootData?.selectedLocale ?? DEFAULT_LOCALE;

return `${selectedLocale.pathPrefix}${
Expand All @@ -280,7 +280,7 @@ export function usePrefixPathWithLocale(path: string) {

export function useIsHomePath() {
const {pathname} = useLocation();
const rootData = useRootLoaderData();
const rootData = useRouteLoaderData<RootLoader>('root');
const selectedLocale = rootData?.selectedLocale ?? DEFAULT_LOCALE;
const strippedPathname = pathname.replace(selectedLocale.pathPrefix, '');
return strippedPathname === '/';
Expand Down
99 changes: 47 additions & 52 deletions app/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
Outlet,
Scripts,
ScrollRestoration,
useLoaderData,
useRouteLoaderData,
useRouteError,
type ShouldRevalidateFunction,
} from '@remix-run/react';
Expand All @@ -25,15 +25,17 @@ import {
} from '@shopify/hydrogen';
import invariant from 'tiny-invariant';

import {Layout} from '~/components/Layout';
import {PageLayout} from '~/components/PageLayout';
import {GenericError} from '~/components/GenericError';
import {NotFound} from '~/components/NotFound';
import favicon from '~/assets/favicon.svg';
import {seoPayload} from '~/lib/seo.server';
import styles from '~/styles/app.css?url';

import favicon from './assets/favicon.svg';
import {GenericError} from './components/GenericError';
import {NotFound} from './components/NotFound';
import styles from './styles/app.css?url';
import {DEFAULT_LOCALE, parseMenu} from './lib/utils';

export type RootLoader = typeof loader;

// This is important to avoid re-fetching root queries on sub-navigations
export const shouldRevalidate: ShouldRevalidateFunction = ({
formMethod,
Expand Down Expand Up @@ -103,10 +105,10 @@ export const meta = ({data}: MetaArgs<typeof loader>) => {
return getSeoMeta(data!.seo as SeoConfig);
};

export default function App() {
function Layout({children}: {children?: React.ReactNode}) {
const nonce = useNonce();
const data = useLoaderData<typeof loader>();
const locale = data.selectedLocale ?? DEFAULT_LOCALE;
const data = useRouteLoaderData<typeof loader>('root');
const locale = data?.selectedLocale ?? DEFAULT_LOCALE;

return (
<html lang={locale.language}>
Expand All @@ -118,30 +120,39 @@ export default function App() {
<Links />
</head>
<body>
<Analytics.Provider
cart={data.cart}
shop={data.shop}
consent={data.consent}
>
<Layout
key={`${locale.language}-${locale.country}`}
layout={data.layout}
{data ? (
<Analytics.Provider
cart={data.cart}
shop={data.shop}
consent={data.consent}
>
<Outlet />
</Layout>
</Analytics.Provider>
<PageLayout
key={`${locale.language}-${locale.country}`}
layout={data.layout}
>
{children}
</PageLayout>
</Analytics.Provider>
) : (
children
)}
<ScrollRestoration nonce={nonce} />
<Scripts nonce={nonce} />
</body>
</html>
);
}

export default function App() {
return (
<Layout>
<Outlet />
</Layout>
);
}

export function ErrorBoundary({error}: {error: Error}) {
const nonce = useNonce();
const routeError = useRouteError();
const rootData = useLoaderData<typeof loader>();
const locale = rootData?.selectedLocale ?? DEFAULT_LOCALE;
const isRouteError = isRouteErrorResponse(routeError);

let title = 'Error';
Expand All @@ -153,37 +164,21 @@ export function ErrorBoundary({error}: {error: Error}) {
}

return (
<html lang={locale.language}>
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>{title}</title>
<Meta />
<Links />
</head>
<body>
<Layout
layout={rootData?.layout}
key={`${locale.language}-${locale.country}`}
>
{isRouteError ? (
<>
{routeError.status === 404 ? (
<NotFound type={pageType} />
) : (
<GenericError
error={{message: `${routeError.status} ${routeError.data}`}}
/>
)}
</>
<Layout>
{isRouteError ? (
<>
{routeError.status === 404 ? (
<NotFound type={pageType} />
) : (
<GenericError error={error instanceof Error ? error : undefined} />
<GenericError
error={{message: `${routeError.status} ${routeError.data}`}}
/>
)}
</Layout>
<ScrollRestoration nonce={nonce} />
<Scripts nonce={nonce} />
</body>
</html>
</>
) : (
<GenericError error={error instanceof Error ? error : undefined} />
)}
</Layout>
);
}

Expand Down
8 changes: 5 additions & 3 deletions app/routes/($locale).cart.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Await} from '@remix-run/react';
import {Await, useRouteLoaderData} from '@remix-run/react';
import invariant from 'tiny-invariant';
import {
type LoaderFunctionArgs,
Expand All @@ -13,7 +13,7 @@ import {

import {isLocalPath} from '~/lib/utils';
import {Cart} from '~/components/Cart';
import {useRootLoaderData} from '~/hooks/useRootLoaderData';
import type {RootLoader} from '~/root';

export async function action({request, context}: ActionFunctionArgs) {
const {cart} = context;
Expand Down Expand Up @@ -90,7 +90,9 @@ export async function loader({context}: LoaderFunctionArgs) {
}

export default function CartRoute() {
const rootData = useRootLoaderData();
const rootData = useRouteLoaderData<RootLoader>('root');
if (!rootData) return null;

// @todo: finish on a separate PR
return (
<>
Expand Down

0 comments on commit d4f92d4

Please sign in to comment.