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

Updating state with shallow false makes multiple reenders #370

Closed
juliomuhlbauer opened this issue Oct 18, 2023 · 12 comments
Closed

Updating state with shallow false makes multiple reenders #370

juliomuhlbauer opened this issue Oct 18, 2023 · 12 comments
Labels
next.js Issue is related to Next.js internals rather than this library

Comments

@juliomuhlbauer
Copy link

juliomuhlbauer commented Oct 18, 2023

When changing the search param with shallow: false, makes multiple reenders on client and blocks the RSC to refetch when the client component is heavy.

@juliomuhlbauer juliomuhlbauer changed the title Updating state with shallow makes multiple reenders Updating state with shallow false makes multiple reenders Oct 18, 2023
@franky47
Copy link
Member

Do you have a reproduction example?

Having multiple renders is expected as there is at least one when the state updates, and one per Suspense boundary when its RSC payload resolves from either the server or the local client cache.

@juliomuhlbauer
Copy link
Author

juliomuhlbauer commented Oct 20, 2023

I think that is a Nextjs problem.
I am testing this to give a real reproduction. But I have a reproduction showing some reendes in useSearchParams()

https://search-param-wine.vercel.app/

https://github.com/juliomuhlbauer/search-param/

Try to click in the links to change the search params. For now the Select does nothing.

I will expand the reproduction to show when the UI is heavy.

@juliomuhlbauer
Copy link
Author

juliomuhlbauer commented Oct 20, 2023

Now I made an example with the next-usequerystate and it causes multiple reenders.

This example doesn't block the UI. But when it is with heavy UI it blocks.

https://search-param-nqx9ne9vw-juliomuhlbauer.vercel.app/use-query

Check de console

https://github.com/juliomuhlbauer/search-param/

image

@juliomuhlbauer
Copy link
Author

Made an directory with a heavy UI. Well is not that heavy, but it blocks the render.

https://search-param-wine.vercel.app/use-query-with-select

@juliomuhlbauer
Copy link
Author

juliomuhlbauer commented Oct 20, 2023

A workaround kind of works: https://search-param-wine.vercel.app/use-query-with-select-in-layout-custom

But is does give an error of React and it does not get the value SSR.

image

@franky47
Copy link
Member

franky47 commented Oct 22, 2023

Thanks, I was able to reproduce on my end, will take a look.

I found on the playground that there are two renders on the first query update after a hard reload of the page, but only one for subsequent updates, not sure why.

Also, in development, React will use strict mode which performs two render passes per actual render to fish out incorrect useEffect usage, so checking for renders should be done in a production build.

@juliomuhlbauer
Copy link
Author

Try removing the useSearchParam hook. I think Nextjs makes a reender whithin the Suspense boundary and causes the UI to reender multiple times.

I created a alternative hook for useSearchParam, but it only works client side. So need to import dynamically without ssr.

@juliomuhlbauer
Copy link
Author

Maybe this involves the behavior of useSearchParams: https://nextjs.org/docs/app/api-reference/functions/use-search-params#behavior

I dont't know why its different from the useParams hook.

@franky47
Copy link
Member

franky47 commented Nov 8, 2023

I was able to get a render loop without using next-usequerystate on the /use-query-with-select page, by setting the querystring directly with the Next.js router:

  const router = useRouter()
  const cidade = 'readonly'
  const setCidade = React.useCallback(
    (city: string) => {
      router.replace('?cidade=' + city, { scroll: false })
    },
    [router]
  )
  // const [cidade, setCidade] = useQueryState(
  //   TEST_PARAM,
  //   parseAsString
  //     .withOptions({
  //       shallow: false,
  //     })
  //     .withDefault('Taubaté')
  // )

I doubt there much I can do if your UI behaves like this with the stock Next.js router unfortunately..

@franky47 franky47 added the next.js Issue is related to Next.js internals rather than this library label Nov 8, 2023
@juliomuhlbauer
Copy link
Author

Thanks! I opened an issue to the Ark UI library: chakra-ui/ark#1738

But I think it is a Nextjs bug.

@juliomuhlbauer
Copy link
Author

I opened an issue on Nextjs: vercel/next.js#58684

@franky47
Copy link
Member

Closing as unrelated to nuqs (behaviour is reproducible without it).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
next.js Issue is related to Next.js internals rather than this library
Projects
None yet
Development

No branches or pull requests

2 participants