Skip to content

Commit

Permalink
Merge pull request #124 from Shopify/@juanpprieto/refactor-hooks
Browse files Browse the repository at this point in the history
Add useDeferred and improve useCart and useCountries
  • Loading branch information
juanpprieto authored Oct 26, 2022
2 parents 5ae103c + 1bd59c6 commit 3f7f843
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 34 deletions.
17 changes: 4 additions & 13 deletions app/hooks/useCart.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
import {useParentRouteData} from './useRouteData';

import {useMatches} from '@remix-run/react';
import {useDeferred} from './useDeferred';
import type {Cart} from '@shopify/hydrogen-ui-alpha/storefront-api-types';

/*
This is an experimental pattern that helps prevent props drilling
*/
export function useCart(): Cart | null {
const rootData = useParentRouteData('/');

if (typeof rootData?.cart === 'undefined') {
return null;
}

if (rootData?.cart?._data) {
return rootData?.cart?._data;
}

throw rootData?.cart;
const [root] = useMatches();
return useDeferred('cart', root);
}
17 changes: 4 additions & 13 deletions app/hooks/useCountries.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
import {useParentRouteData} from './useRouteData';

import {useMatches} from '@remix-run/react';
import {useDeferred} from './useDeferred';
import type {Country} from '@shopify/hydrogen-ui-alpha/storefront-api-types';

/*
This is an experimental pattern that helps prevent props drilling
*/
export function useCountries(): Array<Country> | null {
const rootData = useParentRouteData('/');

if (typeof rootData?.countries === 'undefined') {
return null;
}

if (rootData?.countries?._data) {
return rootData?.countries?._data;
}

throw rootData?.countries;
const [root] = useMatches();
return useDeferred('countries', root);
}
28 changes: 28 additions & 0 deletions app/hooks/useDeferred.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import {RouteMatch} from '@remix-run/react';

/*
A utility hook to access defer props from a given route
*/
export function useDeferred(resource: string, route: RouteMatch) {
if (!route) {
throw new Error('route not provided');
}
if (!resource) {
throw new Error('resource not provided');
}
const isPromise = Boolean(route?.data?.[resource]?.then);

if (isPromise) {
// the [resource] promise resolved, returned promised data
if (route?.data?.[resource]?._data) {
return route?.data?.[resource]?._data;
}

// Promise not yet resolved, throw while data is ready
// Must be caught by a wrapping suspense boundary
throw route?.data?.[resource];
}

// the [resource] was awaited in the loader return it
return route.data[resource];
}
8 changes: 0 additions & 8 deletions app/hooks/useRouteData.tsx

This file was deleted.

0 comments on commit 3f7f843

Please sign in to comment.