Consuming the withLoader HOC

Consuming a HOC is very simple. We simply wrap the HOC around the component that we want to enhance. The easiest place to do this is in the export statement.

Let's add the withLoader HOC we created in the previous section to our product page:

  1. So, we are going to wrap the Product component with withLoader. First, let's import withLoader into Product.tsx:
import withLoader from "./withLoader";
  1. Now we can wrap withLoader around Product in the export statement:
export default withLoader(Product);

We now get a compilation error in the ProductPage component because it expects to pass Product a loading property.

  1. So, let's pass the loading property from the loading state where we reference Product in ProductPage:
<Product
loading={this.state.loading}
product={product}
inBasket={this.state.added}
onAddToBasket={this.handleAddClick}
/>
  1. Whilst still in ProductPage.tsx, we should revise the condition that renders the Product component. We now want to render Product if the product is still being loaded. This will then render the loading spinner:
{product || this.state.loading ? (
<Product
loading={this.state.loading}
product={product}
inBasket={this.state.added}
onAddToBasket={this.handleAddClick}
/>
) : (
<p>Product not found!</p>
)}

This gives us another compilation error, though, because the product property within the Product component doesn't expect to be undefined. However, it will be undefined when the product is being loaded.

  1. So, let's make this property optional in IProps for the Product component:
interface IProps {
product?: IProduct;
inBasket: boolean;
onAddToBasket: () => void;
}

This then gives further compilation errors in the JSX in the Product component where we reference the product property because it now will be undefined during the loading of the data.

  1. A simple resolution to this is to render null if we don't have a product. The withLoader HOC that wraps Product will render a loading spinner in this case, anyway. So, we are just keeping the TypeScript compiler happy here:
const handleAddClick = () => {
props.onAddToBasket();
};
if (!product) {
return null;
}
return (
<React.Fragment>
...
</React.Fragment>
);

Now that the TypeScript compiler is happy, if we go to the product page in our shop it will display our loading spinner before rendering the product:

So, HOCs are great for enhancing components where the enhancement is something that can be applied to many components. Our loader spinner is a common use case for a HOC. Another very common usage of the HOC pattern is when using React Router. We used the React Router withRouter HOC previously in this book to access parameters for a path. 

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.245.196