taurOan
taurOan

Reputation: 217

useInfiniteQuery doesn't keep previous data (react-query)

I'm trying to implement useInfiniteQuery for pagination scroll with filters for a backend that doesn't support pagination cursor (I'm using limit and start parameters). I was able to retrieve my data but my hasNextPage variable is always undefined. I cannot fetch more data. When the button is used to trigger fetchNextPage, new data can be seen but it removes the previous data.

console

What am I doing wrong ? Here is my code:

// Query data
  const { 
      data, 
      status, 
      error, 
      isSuccess, 
      hasNextPage,
      fetchNextPage, 
      isFetching,
      isFetchingNextPage, 
      isLoading,
      isError,
  } = useInfiniteQuery(
    [
      'vendors',
      {vendor_type: vendorTypesId}, 
      {country: countryId}, 
      {city: cityId}, 
      {vendor_product_types: productCategoryId}, 
      {page: thisPage}, 
      {start: start}, 
      {name: nameInput},
      {limit: limit},
    ],
    getVendors, 
   { 
      initialData: {
        pages : [{
          result: vendors,
          resultCount: 495,
          pageId: 0,
          nextPageId: 15
        }], 
        pageParams: startParams
      }
    },
    {getNextPageParam: (lastPage, pages) => lastPage.nextPageId}
    {keepPreviousData: true}
  ) 

Update: hasNextPage was always undefined beacause getNextPageParam and initialData were in two separated objects. I corrected it like this :

{ 
      initialData: {
        pages : [{
          result: vendors,
          resultCount: 495,
          pageId: 0,
          nextPageId: 15
        }], 
        pageParams: startParams
      },
    
       getNextPageParam: (lastPage, pages) => lastPage.nextPageId
}

It now returns true but clicking on the button still erase the previous data.

Upvotes: 5

Views: 10466

Answers (1)

TkDodo
TkDodo

Reputation: 28733

I think you have the same problem as described in your update: react-query only takes one options object, where you should put all options like initialData, getNextPageParam and keepPreviousData, so something like:

useInfiniteQuery(
  'key',
  queryFn,
  {
    initialData: {...},
    getNextPageParam: () => ...,
    keepPreviousData: true,
  }
)

also, please be aware that initialData is also applied when the query key changes, because a new cache entry is created. So by supplying initialData, keepPreviousData might become irrelevant because the previous data is only shown until you have correct data for your new query key. And since initialData is persisted to the cache, it is treated as a valid response for the new query key.

if you only want to apply initialData to a specific query key (like the one that you show initially, where not filters are applied), you need to make sure of that yourselves: Set initialData to undefined for all keys where you don't want initial data, and set it to something for all the keys where you want it.

Upvotes: 6

Related Questions