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

1

5

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.

Leukocyte answered 26/9, 2021 at 19:59 Comment(0)
F
6

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.

Felly answered 27/9, 2021 at 15:52 Comment(1)
Thank you, this has gave me a better insight. I wasn't sure on how to operate your recommandation so to avoid confusion between "initialData" and new queries data, I simply replaced "getNextPageParam: (lastPage, pages) => lastPage.nextPageId" by "(lastPage, pages) => pages.length * limit" and it now seems to work...!Leukocyte

© 2022 - 2024 — McMap. All rights reserved.