Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

prefetchInfiniteQuery - Next.js SSR - Error serializing .dehydratedState.queries[0].state.data.pageParams[0] #1458

Closed
yayvery opened this issue Dec 16, 2020 · 26 comments
Labels

Comments

@yayvery
Copy link
Contributor

yayvery commented Dec 16, 2020

SerializableError: Error serializing .dehydratedState.queries[0].state.data.pageParams[0] returned from getServerSideProps in "/[[...sort]]". Reason: undefined cannot be serialized as JSON. Please use null or omit this value.

The pageParams array when using prefetchInfiniteQuery is returning [undefined], which cannot be serialized by Next.js. It should return a single element array of the page param that was used to prefetch the infinite query (i.e. [0]).

@yayvery yayvery changed the title prefetchInfiniteQuery Next.js SSR - Error serializing .dehydratedState.queries[0].state.data.pageParams[0] prefetchInfiniteQuery - Next.js SSR - Error serializing .dehydratedState.queries[0].state.data.pageParams[0] Dec 16, 2020
@jorgemasta
Copy link

Are you using initialData ?
If so, you probably have to set the pageParams too.

E.g:

initialData: {
  pages: [ myFirstPage ],
  pageParams: [1]
}

@yayvery
Copy link
Contributor Author

yayvery commented Dec 17, 2020

@jorgemasta no, I am using prefetchInfiniteQuery and hydration.

@yayvery
Copy link
Contributor Author

yayvery commented Dec 17, 2020

It's the same problem as in #1370

@tannerlinsley
Copy link
Collaborator

#1370 was within our control to fix, but this one is definitely more userland. I think we should file an issue upstream with Next about this instead.

@tannerlinsley
Copy link
Collaborator

The best workaround for now would be to JSON.parse(JSON.stringify(dehydrate(queryClient)))

@yayvery
Copy link
Contributor Author

yayvery commented Dec 17, 2020

@tannerlinsley But why should react-query return pageParams: [undefined] when using prefetchInfiniteQuery? Shouldn't it return pageParams: [0] if the pageParam used to prefetch the query is 0?

In queryCache.test.tsx:

expect(result).toEqual({
      pages: [10],
      pageParams: [undefined],
    })

@tannerlinsley
Copy link
Collaborator

Yes it should actually. We should probably dig into that. But regardless, it is possible for a pageParam to be undefined for a page, so we should cover this edge case either way :)

@tannerlinsley
Copy link
Collaborator

Pretty stale issue here, and I haven't seen any more reports of it since. Closing for now.

@nubpro
Copy link
Contributor

nubpro commented Jan 11, 2021

Pretty stale issue here, and I haven't seen any more reports of it since. Closing for now.

May I know what's the proper solution?
I'm still getting this error

image

@Honason
Copy link

Honason commented Jan 11, 2021

I agree, please consider fixing this. When anyone follows the directions described and shown in official documentation, it results in this crash when using infinite query. And it seems like it would be uncomplicated fix. Doing JSON.parse(JSON.stringify(dehydrate(queryClient))) works, but I hope that it will not be the recommended (and only) way to avoid this issue.

@nubpro
Copy link
Contributor

nubpro commented Jan 11, 2021

Here's a repro sandbox for good measure:
https://codesandbox.io/s/magical-engelbart-1ucsv?file=/pages/index.js

On another note is that after applying the workaround, after going back to the index page from the about page, the scroll seems to stick to the top and the cached data is gone. Is this a side effect?

@waptik
Copy link
Contributor

waptik commented Jan 12, 2021

I agree, please consider fixing this. When anyone follows the directions described and shown in official documentation, it results in this crash when using infinite query. And it seems like it would be uncomplicated fix. Doing JSON.parse(JSON.stringify(dehydrate(queryClient))) works, but I hope that it will not be the recommended (and only) way to avoid this issue.

I don't think it's a react-query issue. From what i can see it's a nextjs issue so i'm not sure what you need them to fix. Please read the following quote:

#1370 was within our control to fix, but this one is definitely more userland. I think we should file an issue upstream with Next about this instead.

@aulneau
Copy link

aulneau commented Jan 19, 2021

Pretty stale issue here, and I haven't seen any more reports of it since. Closing for now.

This is still an issue, after following the docs as they are, this error is what happens.

@Kae7in
Copy link

Kae7in commented Mar 2, 2021

I'm having this same issue. Using JSON.parse(JSON.stringify(dehydrate(queryClient))) works but feels a bit hacky.

@iksent
Copy link

iksent commented Mar 17, 2021

Trying to prefetch Infinite query from Next.js and getting the same error:

SerializableError: Error serializing `.dehydratedState.queries[1].state.data.pageParams[0]` returned from `getServerSideProps` in "/".
Reason: `undefined` cannot be serialized as JSON. Please use `null` or omit this value.

My getServerSideProps:

queryClient.prefetchInfiniteQuery(
  useGetArticlesQuery.getKey({ limit: 10 }),
  ({ pageParam = 1 }) => { <<< Default value didn't help
    return fetcher<GetArticlesQuery, GetArticlesQueryVariables>(GetArticlesDocument, {
      ...{ limit: ARTICLES_PER_PAGE },
      page: pageParam,
    })()
  },
  { getNextPageParam: (lastPage) => 1 }, <<< Didn't help
),

@andtos90
Copy link

I fixed the issue using superjson

It's a slightly better solution, but the drawback is the need for a new dependency

@sijad
Copy link

sijad commented Oct 28, 2021

I have faced same problem, fixed like this:

  queryClient.setQueryData(queryKey, (data) => ({
    ...data,
    pageParams: [],
  }));

@MaximeConan
Copy link

I fixed the issue using superjson

It's a slightly better solution, but the drawback is the need for a new dependency

Finally use this solution too. Not ideal but better to set each query manually ! Thanks @andtos90

@sethmbrown
Copy link

Bumping this issue as we ran into it again. Definitely want to avoid setting the query manually in our case, so if there's a way to define a default pageParam or have it return null rather than undefined, we'd be super appreciative. Thanks!

@TkDodo
Copy link
Collaborator

TkDodo commented Jan 26, 2022

we currently use undefined for pageParam returned from getNextPageParam so that we know when to stop refetching. As long as getNextPageParam returns something non-undefined, we keep fetching the next page on refetches (e.g. window focus or invalidation). This is documented here.

https://github.com/tannerlinsley/react-query/blob/a701340efd5fe5751cd4b317be88430533f4d0d7/src/core/infiniteQueryBehavior.ts#L59-L61

The first page is an exception to the rule (we always fetch the first page). For the first page, undefined is used because it allows us to assign a default value in the queryFn, where pageParam is injected. Standard example from the docs:

const fetchProjects = ({ pageParam = 0 }) =>
  fetch('/api/projects?cursor=' + pageParam)
 
const query = useInfiniteQuery('projects', fetchProjects, {
  getNextPageParam: (lastPage, pages) => lastPage.nextCursor,
})

In fetchProjects, the first page fetch will fetch with cursor=0 only because pageParam is undefined.


If we change this behaviour to null, it would be a breaking change, making dx worse for these scenarios. Semantics of null and undefined are also different, but that's debatable 😅 .


What dehydration does is merely make a reduced js object out of the queryClient. We also use that mechanism for the persisters. It seems to be a nextJs requirement that js objects returned from getServerSideProps and getStaticProps do not contain undefined values. I don't know the reason behind this, so I still think it is better to open a discussion / issue with Next.

Tbh, I was surprised that the JSON.parse(JSON.stringify()) workaround does work, because it actually turns:

 pageParams: [undefined]

into

 pageParams: [null]

I think this only works coincidentally, because we ignore the pageParam completely when fetching the first page:

https://github.com/tannerlinsley/react-query/blob/a701340efd5fe5751cd4b317be88430533f4d0d7/src/core/infiniteQueryBehavior.ts#L81-L84


Since v4 is around the corner, and the first element in pageParams apparently doesn't matter, we could think about changing it to null before writing it to the cache, after we have passed it to the queryFn (there, we would still need undefined for the destructuring to work). Also feels a bit hacky. If anyone has other ideas, please shoot :)

kingyong9169 added a commit to SWM-re-pashion/repashion-client that referenced this issue Sep 26, 2022
## 💡 이슈
resolve #93 

## 🤩 개요
shop 피드 api 연결 및 SSR 추가입니다.

## 🧑‍💻 작업 사항

- [x] api 코드 및 hook 작성
- [x] shop피드 query string 넣기
- [x] PullToRefresh api 붙이기
- [x] 상품이 없을 경우 UI 추가 및 style 버그 수정
- [x] SSR

## 📖 참고 사항

SSR 이슈입니다.
`Nest.js`에서 `pageParams`의 `0번 index값`이 `undefined`로 들어오는 이슈입니다.
TanStack/query#1458

### 무한 스크롤

https://user-images.githubusercontent.com/62797441/192363166-e5244762-5ccb-408c-b43a-3be81abfb838.mov

### Pull To Refresh

https://user-images.githubusercontent.com/62797441/192363248-297de6fb-a348-45d0-a2e1-23cae9f048fe.mov

### feed 옵션 클릭 시 새로운 결과 불러오기 및 상품 결과 없을 경우 UI
영상을 보면 엄청 깜박입니다. 백엔드에서 `isEndofPage`로직이 아직 덜 완성되어 계속 `fetchNextPage`가
동작하기 때문입니다.


https://user-images.githubusercontent.com/62797441/192363451-3e1dd8f3-7661-4385-855b-993cb903aeb8.mov
@mkbctrl
Copy link

mkbctrl commented May 3, 2023

Just wanted to report that the issue is still present in Nextjs 12.2.5 + RQ 4.29.1. Hacky workarounds solves the issue.

@TkDodo
Copy link
Collaborator

TkDodo commented May 3, 2023

we have a fix for this with v5, you can try out the alpha version already:

https://tanstack.com/query/v5/docs/react/guides/migrating-to-v5#infinite-queries-now-need-a-defaultpageparam

@TkDodo TkDodo added v5 and removed upstream labels May 3, 2023
@Butonix
Copy link

Butonix commented May 13, 2023

we have a fix for this with v5, you can try out the alpha version already:

https://tanstack.com/query/v5/docs/react/guides/migrating-to-v5#infinite-queries-now-need-a-defaultpageparam

I did everything as it is written in the documentation. srr doesn't work anyway

export default function useComments(id: string, sortParam: string) { return useInfiniteQuery<Response, Error>({ queryKey: ['comments', id, sortParam], queryFn: ({ pageParam }) => fetchComments(id, pageParam, sortParam), defaultPageParam: 0, getNextPageParam: (lastPage) => lastPage.nextCursor, }); }

queryClient.prefetchInfiniteQuery({ queryKey: ["comments", query.id, sort], queryFn: () => fetchComments(query.id as string, 0, sort), defaultPageParam: 0, }),

@TkDodo
Copy link
Collaborator

TkDodo commented May 14, 2023

I did everything as it is written in the documentation. srr doesn't work anyway

can you show this in a codesandbox reproduction please?

fnocetti pushed a commit to fnocetti/ideal-adventure that referenced this issue Oct 10, 2023
@d90375
Copy link

d90375 commented Mar 28, 2024

still
image
"next": "^14.1.3",
"@tanstack/react-query": "^5.28.4",

@TkDodo
Copy link
Collaborator

TkDodo commented Apr 2, 2024

@d90375 well that's just your data (clientName) being undefined ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests