nextJS SSR useRouter() does not work when refresh page
Asked Answered
D

5

10

I am using nextJS SSR in my project. Now when I try to use the following code to get page parameters then it shows undefined.

 function About() {
  const router = useRouter();
  const { plan_id } = router.query;
  console.log(plan_id)
 }
 export default About;

It works when the page is routed from some other page (without page reload with "next/link") but it does not work when I refresh the page. Can someone please help?

Dryly answered 1/9, 2020 at 16:0 Comment(1)
The reason is how Next handle the Automatic static optimization pages. See nextjs.org/docs/routing/dynamic-routes#caveats and good example with useSWR here : github.com/vercel/next.js/discussions/15952Courtneycourtrai
D
18

I found the answer self. Actually when you refresh the page then the router does not get initialized instantly. So you can add that under UseEffect hook as following and you will be able to get the parameters

function About() {

 const [param1, setParam1]=useState("");
 const router = useRouter();

 useEffect(() => {
  if (router && router.query) {
   console.log(router.query);
   setParam1(router.query.param1);
  }
 }, [router]);
}

When this router parameter will change then it will call the "UseEffect" which can be used to retrieve the values.

Dryly answered 1/9, 2020 at 17:22 Comment(0)
W
7
 function About({plan_id}) {
  console.log(plan_id)
 }

 // this function only runs on the server by Next.js
 export const getServerSideProps = async ({params}) => {
    const plan_id = params.plan_id;
    return {
       props: { plan_id }
    }
 }

 export default About;
  • You can find more intel in the docs.
Whap answered 2/9, 2020 at 6:10 Comment(2)
Thanks Aman, You are right. I can also get the parameters in this way even on refresh. Thanks again.Dryly
Given that Next.js is also a Static Site Generator that produces sites that run purely client side, saying "do it server side" isn't the most helpful answer.Tamarau
A
0

I fix this problem with this method.

First add getServerSideProps to your page

//MyPage.js
export async function getServerSideProps({req, query}) {

       return {
            props: {
                initQuery: query
            }
        }
}

Then created useQuery function like this

//useQuery.js
export let firstQuery = {}
export default function useQuery({slugKey = 'slug', initial = {}} = {}) {
    const {query = (initial || firstQuery)} = useRouter()

    useEffect(() => {
        if (_.isEmpty(initial) || !_.isObject(initial))
            return
        firstQuery = initial
    }, [initial])

    
return useMemo(() => {

    if (!_.isEmpty(query)) {
        return query
    }
    try {
        const qs = window.location.search.split('+').join(' ');

        const href = window.location.href
        const slug = href.substring(href.lastIndexOf('/') + 1).replace(/\?.*/gi, '')

        let params = {},
            tokens,
            re = /[?&]?([^=]+)=([^&]*)/g;
        if (slug)
            params[slugKey] = slug


        while (tokens = re.exec(qs)) {
            params[decodeURIComponent(tokens[1])] = decodeURIComponent(tokens[2]);
        }


        return params
    } catch {
    }
}, [query])
}

And always use useQuery for receive query params

//MyPage.js
export default function MyPage({initQuery}) {
     const query = useQuery({initial: initQuery})

    return(
      <div>
           {query.myParam}
      </div>
    )
}

And in components like this

//MyComponent.js
export default function MyComponent() {
     const query = useQuery()

    return(
      <div>
           {query.myParam}
      </div>
    )
}
Averell answered 14/3, 2022 at 13:38 Comment(0)
A
0

Same thing happened with me when working on Next.js Routing. NextJS is set to be Server side rendering by default, because of that when we reload the page we do not get the query String immediately because it is server side. Try using UseEffect and try to update the query , until then keep the page busy and block using If condition and when the page is finally rendered then pass it from condition.

Astro answered 8/6, 2023 at 12:17 Comment(0)
S
-1

For those still having issues with this. Here is a solution that worked for me

function About() {

 const [param1, setParam1]=useState("");
 const router = useRouter();
 const { param1 } = router.query() 

 useEffect(() => {
  if (!param1) {
   return;
 }

 // use param1
 }, [param1]);
}

You can find the solution here

Seraphim answered 10/11, 2021 at 21:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.