본문 바로가기
Front-End/NextJS

[NextJS] SyntaxError: Unexpected token u in JSON at position 0 - router.query undefiend 해결하기

by 흐암졸령 2022. 6. 28.
반응형

[ 문제점 ]

Next Js의 이전 페이지에서 query를 사용해 값들을 넘겨주고 이 값들을 가져와 사용하려고 하였다. 전달하는 값이 json이라서 JSON.stringify을 하여서 보내고, JSON.parse함수를 사용해서 받으려고 하였다. 그래서 다음과 같은 코드로 실행을 하였는데 오류가 나왔다.

import {useEffect} from "react";
import {useRouter} from "next/router";

export default function App() {
  const router = useRouter();
  
  useEffect(() => {
    console.log(JSON.parse(router.query.dict as string));
  }, []);
  
  return (
    <div>
      {router.query}
    </div>
  )
}

SyntaxError: Unexpected token u in JSON at position 0

[ 문제 원인 ]

해당 오류는 JSON.parse에 undefiend의 값이 들어갔기 때문에 생긴 오류였습니다. 그렇다면 JSON.parse에 undefiend가 들어간 이유로는 Next Js의 useRouter을 통해서 얻은 router의 작동 방식때문에 생긴 것 입니다.

During prerendering, the router's query object will be empty since we do not have query information to provide during this phase. After hydration, Next.js will trigger an update to your application to provide the route parameters in the query object.
 

Advanced Features: Automatic Static Optimization | Next.js

Next.js automatically optimizes your app to be static HTML whenever possible. Learn how it works here.

nextjs.org

사전 렌더링 중에는 제공할 쿼리 정보가 없으므로 router의 쿼리는 비어있다. 하이드레이션 후, 쿼리 객체에 router parameter를 제공하기 위해 업데이트 한다.

정적 파일 최적화에 의해서 사전 렌더링에는 쿼리 파라미터가 제공되지 않고, 이로 인해서 오류가 생긴 것이었다.

 

[ 해결방법 ]

쿼리 파라미터가 존재하지 않아서 생긴 오류이므로 해결하는 방법으로는 크게 두 가지가 있다. 첫 번째는 router가 client에서 사용할 준비가 되었는지 판단한 후 사용하는 방법이다.

 

router.isReady - NextJS@10.0.5 이후

import {useEffect} from "react";
import {useRouter} from "next/router";

export default function App() {
  const router = useRouter();
  
  useEffect(() => {
    if (!router.isReady) return null;
    console.log(JSON.parse(router.query.dict as string));
  }, [router.isReady]);
  
  return (
    <div>
      {router.query}
    </div>
  )
}

router의 isReady를 사용해서 클라이언트 측에서 업데이터되고 사용할 준비가 되어있는지를 확인한다. 이는 useEffect 메소드 내부에서만 사용하여야 하고, dependency로 router.isReady를 추가해 주어야 한다.

 

 두 번째 방법은 window의 location을 불러와 사용하는 방법이다. window.location.search의 값과 URLSearchParams 메소드를 사용하면 url의 쿼리 파라미터를 읽거나 수정할 수 있다.

 

URLSearchParams - NextJS@10.0.5 이전

import {useEffect} from "react";
import {useRouter} from "next/router";

export default function App() {
  const router = useRouter();
  
  useEffect(() => {
    const urlSearchParams = new URLSearchParams(window.location.search);
    const query = urlSearchParams.get('dict');
    console.log(JSON.parse(query));
  }, []);
  
  return (
    <div>
      {router.query}
    </div>
  )
}

이때의 window 객체는 무조건 useEffect 내부에서만 사용하여야 한다. window은 SSR동안에서는 존재하지 않는데, useEffect는 DOM이 생긴 이후에 실행하므로 이 내부에서만 작동할 수 있다. 필자의 경우에는 router.isReady를 사용하여서 해당 문제를 해결하였다.

반응형

댓글