Algolia Search Re-Rendering With Next.JS & Shopify

Algolia Search Re-Rendering With Next.JS & Shopify

Implementation :

The frontend is built with Next.js, while Shopify serves as the backend. Algolia's react-instantsearch library powers product data display on Product Listing Pages (PLPs). The collection.js component fetches product data from Algolia and passes it to the ProductItemTile.js component for rendering. Each PLP displays approximately 102–104 products per page. To supplement incomplete data from Algolia, a get-plp-product-data API retrieves additional product details from Shopify within the ProductItemTile.js component.


Challenge :

Reloading the PLP triggers multiple get-plp-product-data API calls, exceeding the number of products on the page for all pages except the first.


Debugging

  • Inspect useEffect in ProductItemTile.js

Check if the get-plp-product-data API call is inside a useEffect. If it is, ensure the dependency array is correct.

useEffect(() => {
  fetchProductDetails();
}, []); // Empty dependency array might still cause issues if props change unexpectedly.        

Verify Unique Identifiers

  • Ensure each product rendered in ProductItemTile.js has a unique identifier (e.g., key in the React component). If React can't uniquely identify components, it may remount them unnecessarily.

{products.map((product) => (
  <ProductItemTile key={product.id} product={product} />
))}        

Memoization with React.memo or useMemo

  • Use React.memo or useMemo to memoize components or data where applicable. This will prevent redundant renders when the data has not changed.

export default React.memo(ProductItemTile);        

Or memoizing computed product data:

const productData = useMemo(() => {
  return calculateProductData();
}, [dependencies]);        

Optimize API Call in ProductItemTile.js

  • Move the get-plp-product-data API call to the parent collection.js or a higher-level component, so all product details are fetched in a batch.
  • Pass the fetched details as props to ProductItemTile.js. This avoids multiple API calls per product.

const productData = await Promise.all(
  products.map(product => fetch(`/api/get-plp-product-data?id=${product.id}`).then(res => res.json()))
);        

Pagination-Specific Behavior

  • Check how pagination is implemented in collection.js. When navigating to a different page, ensure the component is not unnecessarily unmounting and remounting.
  • Ensure pagination maintains state correctly, avoiding re-fetching data unnecessarily.


Solution :

Refactor API Call to Parent Component

  • Fetch Shopify product data in collection.js or a custom hook to centralize data fetching and prevent redundant calls.

const fetchProductData = async (products) => {
  const productDetails = await Promise.all(
    products.map(product => fetch(`/api/get-plp-product-data?id=${product.id}`).then(res => res.json()))
  );
  return productDetails;
};

useEffect(() => {
  fetchProductData(algoliaProducts).then((details) => {
    setDetailedProducts(details);
  });
}, [algoliaProducts]);        

  • Pass detailedProducts as props to ProductItemTile.js.


Use React.memo for ProductItemTile.js

  • Prevent re-renders of ProductItemTile.js by wrapping it with React.memo.

const ProductItemTile = React.memo(({ product }) => {
  // Component logic
  return <div>{product.name}</div>;
});        

Ensure Stable Keys

  • Verify that each product has a stable and unique key when rendering the product list.


Pagination Optimization

  • Ensure Algolia pagination does not trigger unnecessary component re-renders. For instance, use onPaginationChange or equivalent to ensure efficient updates.

Let me know if you need further guidance or specific code examples for implementation!


Looking to Build or Upgrade Your E-commerce Store?

?? Contact us today at [email protected]

?? Visit us at: https://w3nuts.co.uk/

要查看或添加评论,请登录

W3NUTS的更多文章

社区洞察

其他会员也浏览了