nextJS SSR useRouter() does not work when refresh page

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?

5 ответов

Решение
  • Если вы хотите получить доступ к параметрам, сделайте это в стиле Next.js. Нет необходимости запускать код на стороне клиента, если данные могут быть предоставлены самим сервером. Это идея SSR.
 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;

Я сам нашел ответ. На самом деле, когда вы обновляете страницу, маршрутизатор не инициализируется мгновенно. Итак, вы можете добавить это в перехватчик UseEffect, как показано ниже, и вы сможете получить параметры

function About() {

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

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

Когда этот параметр маршрутизатора изменится, он вызовет UseEffect, который можно использовать для получения значений.

То же самое произошло со мной, когда я работал над маршрутизацией Next.js. По умолчанию для NextJS настроен рендеринг на стороне сервера, поэтому при перезагрузке страницы мы не получаем строку запроса сразу, потому что это серверная часть. Попробуйте использовать UseEffect и попробуйте обновить запрос, до тех пор держите страницу занятой и блокируйте ее, используя условие If, а когда страница наконец будет отображена, передайте ее из условия.

Я решаю эту проблему с помощью этого метода.

Сначала добавьте getServerSideProps на свою страницу.

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

       return {
            props: {
                initQuery: query
            }
        }
}

Затем создал функцию useQuery, подобную этой

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

И всегда используйте useQuery для получения параметров запроса.

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

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

И в таких компонентах

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

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

Для тех, у кого еще есть проблемы с этим. Вот решение, которое сработало для меня

      function About() {

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

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

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

Вы можете найти решение здесь

Другие вопросы по тегам