Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

useRouter/withRouter receive undefined on query in first render

Tags:

next.js

I got a problem with my dynamic route. It look like this

[lang]/abc

I am trying to get query value from [lang] but when I using useRouter/withRouter i got query during 2-3 render of page ( on first i got query.lang = undefined ). its possible to get in 1 render or use any technique ?

enter image description here

like image 348
Przemek eS Avatar asked Apr 05 '20 09:04

Przemek eS


People also ask

Why would withRouter router query be empty on first render in Nextjs?

It seems because when refreshing page, the router. query is empty initially. After I put it in the render function, it will re-render the page after router. query is updated.

How do I get a router query in next JS?

The easiest way to get query parameters from a URL in Next. js is by calling the UseRouter() method. The UseRouter() method gives the developer a router object that has a property called query that contains a dictionary of the query parameters for a given URL.

What is shallow routing?

Shallow routing allows you to change the URL without running data fetching methods again, that includes getServerSideProps , getStaticProps , and getInitialProps . You'll receive the updated pathname and the query via the router object (added by useRouter or withRouter ), without losing state.


2 Answers

I found something:

isReady: boolean - Whether the router fields are updated client-side and ready for use. Should only be used inside of useEffect methods and not for conditionally rendering on the server. https://nextjs.org/docs/api-reference/next/router#router-object

And the code would be like:

const router = useRouter();
useEffect(()=>{
    if(!router.isReady) return;

    // codes using router.query

}, [router.isReady]);
like image 167
dy063 Avatar answered Dec 09 '22 23:12

dy063


It isn't possible to get a query value at the first render.

Statically optimized pages are hydrated without provided route parameters. E.g. query is an empty object ({}).

After hydration, Next.js will fill the query object.

Next.js 10.0.5 and up

Use router.isReady inside useEffect hook to check if params are ready. See the answer by @doxylee for the example.

Before Next.js 10.0.5

At first render of a dynamic route router.asPath and router.route are equal. Once query object is available, router.asPath reflects it.

You can rely on the query value within a useEffect hook after asPath has been changed.

const router = useRouter();

useEffect(() => {
  if (router.asPath !== router.route) {
    // router.query.lang is defined
  }
}, [router])

GitHub Issue - Add a "ready" to Router returned by "useRouter"

like image 42
Nikolai Kiselev Avatar answered Dec 09 '22 23:12

Nikolai Kiselev