the_lar's avatar

Seeking help with React app

Hi all,

I'm pretty new to React and have hit a wall with something I'm trying to build, can anyone help?

I've mocked up what I'm trying to do here - https://codesandbox.io/p/sandbox/blazing-firefly-vvfsrf

The app will (eventually) display products in groups of x set by the PAGE_SIZE constant in Wheels.tsx.

App.js sets up 4 different sort orders for the products, default, price high to low, price low to high and popularity in the WheelIdsSortOrder constant. There's a constant for filters in there too, but not currently using that.

This all works in that it loads Ids in pages of 12, then when a new sort order is selected it changes the order and resets the page to 1.

Now, what I need to do is load the data for the Ids that are being loaded, so the Product name, Image, permalink and various other things - this will be via an Ajax request. What I must avoid though is loading the data for ALL of the Ids again and again, I only want to load the next page without refreshing the previously loaded ones.

As I say, I'm pretty new with React so I may be completely wrong, but I was wondering if this is a use case for useMemo? Can anyone provide some help here, most important to me is the explanation of why more than the how if possible?

Much appreciated K

0 likes
2 replies
LaryAI's avatar
Level 58

Absolutely, this is a classic situation in React, and you're right to be thinking about optimizing data fetching. I'll walk you through both the why and how so that you understand the approach.

The Problem

  • You want to “page” through product IDs, fetching their details for each page (e.g., 12 per page).
  • When the user changes the sort order or pages forward, you don’t want to refetch data that you have already loaded.
  • Simply fetching all products every time is wasteful.
  • You wondered about using useMemo.

useMemo vs. What You Really Need

useMemo is used to memoize expensive calculations between renders, but it does not persist values between renders; it simply avoids recalculating a value if its dependencies have not changed. It's not designed for caching or storing loaded data between renders or requests.

For data caching, especially with async data like Ajax, you want to use component state. You can also use more advanced libraries like TanStack Query (React Query), but let's solve it with state for learning.

How to Approach This

  1. Cache loaded products in state:
    • Maintain a “product cache” in your component, keyed by product ID.
  2. When loading a new page:
    • Check the cache. Fetch only those product IDs whose data you don’t have yet.
    • Merge new data into the cache; do not remove previous data.
  3. Display products for the current page from the cache.

Example Solution

I'll sketch out the main parts, focusing on the data flow:

App Component (Simplified)

This is an example of how you might wire it up with sort and page state:

Why This Approach Works

  • Efficient: Only fetches data for new, not-yet-cached IDs.
  • No re-fetching: Once loaded, product data is cached in the component state, and you only fetch missing products.
  • Separation of concerns: The cache is independent of paging, sorting, or filtering, so you don't lose product data already retrieved.

Bonus: React Query, SWR, Etc.

For a production app, consider using TanStack Query, which handles this kind of caching and background fetching for you with almost no code.

But understanding the above approach teaches you the data flow and component state management in React.


Summary

  • useMemo does not cache async fetched data, only memoizes calculations between renders.
  • Use a state object as a cache for fetched products.
  • Only fetch what you don't already have, and show loading indicators as needed.
  • This pattern is very common in React apps.

Let me know if you want a React Query or SWR version, or have questions about refining this further!

JakeMiller's avatar

You’re on the right track, but useMemo won’t prevent repeated data fetching — it only caches calculated values. To avoid reloading previously fetched products, store the data in state (like an object keyed by ID) and, when loading a new page, only fetch items that aren’t already in the cache. This approach keeps previously loaded data intact and ensures efficient loading for each new page.

Please or to participate in this conversation.