본문 바로가기
NEXTjs

[Nextjs] useRouter의 query를 useEffect에서 사용하기

by devebucks 2022. 10. 4.
728x90

개요

구현하려는 기능은, 원래 작성되어 있는 블로그 글을 다시, 업데이트하는 기능이다.

우선, 해당 페이지는 pre-rendering이 필요없는 페이지이다. 그래서, CSR을 사용하려고 했다.

nextjs의 dynamic route 스펙을 사용해서, /wirte/[id].js라는 page를 만들었고, [id].js에서 useRouter hook을 사용해서, [id]의 id를 추출했다. 그리고, useEffect hook을 사용해서, nextjs의 api routes의 api를 호출했다. api routes의 url은 '/post/[id]'이다. 그래서, 다음 코드처럼, 호출했는데, 에러가 발생하였다.

/**
 * @description CSR
 */
export default function WriteId() {
  const {
    query: { id },
  } = useRouter()

  useEffect(() => {
    fetch(`/posts/${id}`) 👈
      .then((res) => res.json())
      .then((res) => {
        console.log(res)
      })
    }, [])
  return (<>...</>) 
}

에러 발생

fetch 요청에 id가 undefined임.

 

 

원인

바로, 'write/[id]'로 서버에 요청하면, ssr로 정적페이지가 반환되므로, Automatic Static Optimization가 적용되어서, useRouter훅의 query가 반환되지 않는다. 반면, 이미 클라이언트 사이드로 chnck파일들이 모두 넘어와서, csr이 되고 있는 상황에서, 'write/[id]'로 페이지를 요청하면, 그니까, navigation route로 이동되면, 해당 에러는 발생하지 않는다.

 

automatic static optimization은 자동 정적 최적화이며, 'getServerSideProps'가 있거나, 없거나 자동으로 서버에서 페이지를 정적 생성한다. csr으로 사용할 페이지라도 말이다!  automatic static optimization의 이점은 사용자에게 초고속 로딩 경험을 제공할 수 있다는 것이다.

 

 

결국, 원인은 nextjs에서 ssr 또는 ssg로 만들어진 페이지에서는 useRouter 훅으로 인한 정보를 클라이언트(브라우저)만 알고 있기 때문에, 서버 측에서 페이지를 정적 생성하면서, path 정보를 읽을 수 없기 때문이다.

 

 

 

해결방법

useRouter hook에 프로퍼티 중에 isReady를 사용해서, useEffect가 실행되도록 한다.

export default function WriteId() {
  const {
    query: { id },
    isReady,  👈
  } = useRouter()

  useEffect(() => {
    if (!isReady) return  👈
    console.log(id)
    fetch(`/posts/${id}`)
      .then((res) => res.json())
      .then((res) => {
        console.log(res)
      })
  }, [isReady])  👈
  return (<></>)
}
728x90

댓글