[Next.js] page를 새로고침 하면 router.query가 왜 undefined가 될까?

ryusudol·2023년 7월 16일
post-thumbnail

에러

TypeError: Cannot read properties of undefined.

당연히 값이 있을 줄 알았던 router.query 객체가 undefined라고 한다.


❓새로고침 시 query 객체가 undefined가 되는 이유

Pre-rendering 단계에서는 Next.js가 query 정보를 모르기 때문에 router의 query 객체는 비어있다. Rendering이 끝나고 Hydration 되면 그때 Next.js가 query 객체에 값을 업데이트 한다.

useRouter는 Next.js에서 자체적으로 제공하는 React Hook이다. Facebook 팀(현재 Meta)에서 React.js를 만든 이유 중 하나는 User들에게 우수한 사용자 경험을 제공하기 위함이다. 우수한 사용자 경험 제공을 위해 우선되어야 하는 것은 화면을 최대한 빠르게 띄우는 것이다. 즉, 렌더링을 우선적으로 해야하는 것이다.

useRouter도, 다른 hook들의 작동 메커니즘과 마찬가지로, React 컴포넌트의 선 렌더링이 진행된 후 hydration이 되고나면 Next.js가 query 객체에 값을 업데이트한다. 때문에 새로고침을 하면 router 인스턴스 내 query 객체의 값이 비어있는 것이다. 이 때문에 위와 같은 undefined 에러가 발생한 것이다.


✅ 해결 방법

router에 있는 'isReady' property 사용

router는 'isReady' property를 제공한다. 'isReady'는 hydration 후에 query 객체 update가 완전히 끝나면 true 값으로 업데이트 된다. 이를 활용해 위 에러를 해결할 수 있다.

if (!router.isReady) {
	return <p className="center">Loading . . .</p>;
}

위처럼 query 객체가 비었을 때 일시적으로 Loading Indicator를 띄워주는 필터 코드를 삽입하니 위 에러가 해결되었다.

  • 단, Next.js 13.4 버전 이후 도입된 app router 방식에서는 'useRouter' hook을 'next/router'가 아닌 'next/navigation'에서 import 해야 한다. 'next/navigation'에는 isReady 속성이 없다. 13.4 이상 버전을 사용하는 경우 'useSearchParams' hook과 'usePathname' hook을 함께 사용하여 query 값을 찾으면 된다.

📚 Reference

  1. Next.js by vercel: https://nextjs.org/docs/pages/building-your-application/rendering/automatic-static-optimization
  2. Stack Overflow: https://stackoverflow.com/questions/69412453/next-js-router-query-getting-undefined-on-refreshing-page-but-works-if-you-navi
  3. Apps Love World: https://www.appsloveworld.com/reactjs/200/66/next-js-router-query-getting-undefined-on-refreshing-page-but-works-if-you-navig
profile
📜 코딩 공부 기록

3개의 댓글

comment-user-thumbnail
2023년 7월 16일

잘봤습니다.

1개의 답글
comment-user-thumbnail
2023년 7월 17일

저도 개발자인데 같이 교류 많이 해봐요 ㅎㅎ! 서로 화이팅합시다!

답글 달기