기록
Next.js에서 useSession을 이용하다 생긴 버그
als982001
2023. 7. 5. 21:41
Next.js에서 useSession을 이용하다 생긴 버그이다.
"use client";
import { useSession } from "next-auth/react";
import { useRouter } from "next/navigation";
import { useEffect, useMemo } from "react";
export default async function Write() { // <= 이 부분이 문제였다.
const router = useRouter();
const session = useSession();
useEffect(() => {
if (session.data === null) {
router.push("/");
}
}, [session]);
return (
<div className="p-20">
<h4>글작성</h4>
<form action="/api/post/new" method="POST">
<input name="title" placeholder="Title 입력" />
<input name="content" placeholder="Content 입력" />
<button type="submit">버튼</button>
</form>
</div>
);
}
위의 코드는 write 폴더의 page.js파일로, 글을 작성하기 위한 폼을 렌더링할 페이지이다. useSession을 이용해 현재 로그인한 상황인지 확인을 한다. 만약 로그인한 상황이 아니라면 session.data가 undefined에서 null로 바뀔 것이다. 그래서 session.data가 null일 경우, 다른 곳으로 보내려고 했다. 하지만 /write로 이동하자 페이지가 반응이 없었다. 그래서 한동안 헤매다 async function Write()의 async를 지워보았다. 그랬더니 정상적으로 동작했다.
export default function Write() {
// 이하 생략
이에 대해 구글링을 해봤지만 마땅한 해답을 찾을 수 없었다. 그래서 chatGPT에게 질문을 했고 다음과 같은 답을 얻을 수 있었다.
'useSession()' 훅은 비동기로 작동하며, 내부에서 데이터를 가져오기 위해 비동기 작업을 수행합니다. 따라서, async 키워드를 사용하여 함수를 비동기 함수로 선언하면, 함수가 비동기적으로 실행되기 때문에 예기치 않은 동작이 발생할 수 있습니다.
함수 컴포넌트를 비동기 함수로 선언하면, React는 해당 함수를 동기적으로 호출하여 초기 렌더링을 수행합니다. 그러나 'useSession()' 훅은 비동기 작업을 수행하기 위해 Promise를 반환하므로, 초기 렌더링 중에 비동기 작업이 진행되는 동안 컴포넌트가 중단되거나 여러 번 렌더링될 수 있습니다. 이로 인해 예기치 않은 동작이 발생할 수 있습니다.
따라서, 'useSession()' 훅을 사용하는 경우, 함수 컴포넌트를 비동기 함수로 선언하지 않고, 동기 함수로 유지하는 것이 좋습니다. 대신, 'useEffect()' 훅 내에서 비동기 작업을 수행하고, 해당 작업이 완료되면 상태를 업데이트하거나 필요한 동작을 수행할 수 있습니다. 이렇게 하면 컴포넌트가 적절한 시점에 렌더링되고 예기치 않은 동작을 피할 수 있습니다.
간단히 말해. useSession() 함수는 비동기 작업을 수행하는데, function Write 함수 역시 async에 의해 비동기적으로 실행되어 예상치 못한 현상이 일어났다는 것이다. 이 답변을 보니 Next.js를 공부하면서 async를 생각 없이 이용했었던 것 같다. 확실히 코드를 작성할 때는 신중하게 작성해야겠다.