nextJS SSR useRouter() does not work when refresh page

Viewed 9593

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?

4 Answers

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.

 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.

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>
    )
}

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

Related