Null checks

Add null checks to product, category, and content page

Previously, category and product pages were always guaranteed to render with a category or product prop respectively, even if the data for that page had not yet been fetched. If the data was not available, the pages would render with a mock category or product object, with just a few fields on it.

Whilst this made the category and product page templates simpler in some ways, it meant that we needed checks elsewhere to determine whether a product or category was mocked or not, which added a lot of overhead. It also led to the requirement of a cacheHit prop on category, product, and content pages in order to render a loading state when there was no real category or product data to load.

In 5.0, product and category pages will no longer have a mocked product/category object passed to them, which will require some small changes to the template.

Also, content pages will receive a page prop, which makes it a little easier to work with.

Category

Previously you may have used the cacheHit prop to determine whether or not to show a loading state. Instead, use the existence of the category:

Copy
Copied
const Category = ({ category, result }) => {
  // if there is no category data, render a loading state
  if (!category) {
    return <CategoryLoadingState />;
  }

  // otherwise render the category
  return (
    <CategoryWrapper>
      <CategoryHeader category={category} />
      // etc
    </CategoryWrapper>
  );
};

Product

As with categories, cacheHit was used to determine whether the product was ready for render. Instead, use the existence of the product.

For example:

Copy
Copied
const Product = ({ product }) => {
  const initialVariant = useVariantFromUrl();

  const variantHandler = useProductVariants(product, { initialVariant });

  // Return loading state early if there is no product
  if (!product)
    return (
      <ProductContainer>
        <ProductPageLoadingState />
      </ProductContainer>
    );

  const { selectedVariant, getMissingOptions } = variantHandler;
  const images = product.images || [];
  const parents = getParentOrCanonicalRoute(data?.route?.parents, product);
  const relatedProducts = product.relatedProducts;

  return <ProductContainer>// etc</ProductContainer>;
};

Content Page

Content pages also previously received a cacheHit prop. In 5.0, they will instead receive a page prop, which contains the data for the page.

Copy
Copied
// before
function ContentPage(props) {
  const { result, cacheHit } = props;

  return (
    <>
      <Header>
        <MaxWidth>
          {cacheHit ? (
            result.data.route.object.name
          ) : (
            <LoadingLine heightPx={27} widthRem={15} />
          )}
        </MaxWidth>
      </Header>
      // etc
    </>
  );
}

// after
/// ꜜ ꜜ ꜜ ꜜ ꜜ ꜜ ꜜ ꜜ ꜜ ꜜ ꜜ

function ContentPage(props) {
  const { page } = props;

  return (
    <>
      <Header>
        <MaxWidth>
          {page ? page.name : <LoadingLine heightPx={27} widthRem={15} />}
        </MaxWidth>
      </Header>
      // etc
    </>
  );
}
Copyright © Norce 2023. All right reserved.