Next.js 14 app router Error: Maximum call stack size exceeded 에러

김영천입니다.·2024년 8월 21일
0


에러 발생

Next.js를 개발 중 다음과 같은 에러가 발생했다. call stack이 갑자기 초과되어 함수 실행이 안되고 있었다.

github의 Oauth를 이용하여 Authorization code를 쿼리파라미터에 포함되었을 때 발생했다.

서론

현재 깃허브 api를 이용하여 Oauth를 구현중에 있다.

그렇기 때문에 깃허브로 이동하여 로그인 후, callback url에 존재하는 쿼리 파라미터에 Authorization code를 받아온다.

이 코드를 이용하여 Access token을 깃허브로부터 가져온다. 유저 정보가 필요할 때 이 Access token를 이용하여 유저 정보를 가져온다.

전체적으로는 다음과 같다.

프로젝트에서는 페이지 렌더링 시 code라는 key값의 쿼리 파라미터가 존재하면 getAccessToken이라는 함수를 실행하여 api를 호출한다.

    React.useEffect(()=>{
        const queryString = window.location.search;
        const urlParams = new URLSearchParams(queryString);
        const codeParam = urlParams.get("code");

        if(codeParam){
            getAccessToken(codeParam);
        }

    },[]);

이 api는 암호화된 Access Token값이 있는 cookie를 가져온다.

가설

1. getAccessToken 함수가 recursion하고 있다.

Authorization code가 쿼리 파라미터에 추가되었을 때 발생하고있다.

이때 getAccessToken 함수가 실행되므로 이 함수가 recursion 중이다.

결론

getAccessToken api 코드 내에서 해당 api를 재귀적으로 실행으로 생각했지만, 재귀적으로 실행되고 있는 함수는 확인할 수 없었다.

또한 에러가 없던 커밋과 비교했을 때에도 해당 api코드는 달라진 점이 없었다.

해결

원인

원인은 server component에서 client component로 props를 전달할 때 문제가 발생했다.

export const getAccessToken = async (code:string) => {
    const res = await axios.get(`${process.env.NEXT_PUBLIC_BASE_API_URL}/api/user/getAccessToken?code=${code}`);

    return res;
}

이 함수를 이용하여 api를 호출하게 되는데, 이때 이 코드는 server component에서 실행되고 있었다.

이 문서를 확인해보면 다음과 같이 작성되어 있다.

서버에서 클라이언트 컴포넌트로 props를 전달할 때
서버 컴포넌트에서 data fetch 후, props로 client component에 전달하는 경우가 있다. 이 경우 props는 React에 의해 직렬화가 가능해야 한다.

이때 res는 Promise객체로 직렬화가 불가능하다. 직렬화가 가능한 arguments들은 다음과 같다.

하지만 위의 코드에서 res는 Promise객체로, 직렬화가 불가능하여 다음과 같은 에러가 발생했다.

그렇기 때문에 다음과 같이 코드를 변경했다.

export const getAccessToken = async (code:string) => {
    const res = await axios.get(`${process.env.NEXT_PUBLIC_BASE_API_URL}/api/user/getAccessToken?code=${code}`);
    const _data = res.data;

    
    return _data;
}

res변수는 Promise객체라 직렬화가 불가능하지만, res객체 안에 있는 data는 직렬화가 가능한 json으로 변경하여 client component로 전달하였다.

0개의 댓글