🚨 문제 상황
Next.js로 x(구 트위터) 클론코딩하는 강의를 듣는 중 문제가 발생했다.
나는 분명 강의 코드를 복사해서 내 프로젝트에 붙여 넣었는데 강의처럼 작동하지 않았다.
'use client';
import { useRouter } from 'next/navigation';
import Main from '@/app/(beforeLogin)/_component/Main';
export default function Login() {
const router = useRouter();
router.replace('/i/flow/login');
return <Main />;
}
코드는 이런 단순한 코드이다.
클라이언트에서 로그인 페이지(/login)로 접근할 경우, 내부적으로 router.replace('/i/flow/login')를 통해 리다이렉트 처리를 한다.
강의에서는 로그인 페이지로 접근하면 /login으로 갔다가 /i/flow/login으로 이동하는데
나의 경우에는 /i/flow/login으로 이동하는 요청이 무한 반복되었다.
그리고 Next.js에서는 이런 에러를 띄우고 있었다.
Cannot update a component (`LinkComponent`) while rendering a different component (`Login`). To locate the bad setState() call inside `Login`, follow the stack trace as described in https://react.dev/link/setstate-in-render
지금 <Login /> 컴포넌트가 렌더링 중인데 그 안에서 다른 컴포넌트(LinkComponent)의 상태를 바꾸는 코드가 실행되고 있다는 뜻이다.
렌더링 중에 다른 컴포넌트를 업데이트하면 React가 렌더링 순서를 보장할 수 없고 의도치 않게 무한 루프나 UI 불일치가 발생할 수 있다.
🥁 해결 방법
'use client';
import { useRouter } from 'next/navigation';
import Main from '@/app/(beforeLogin)/_component/Main';
import { useEffect } from 'react';
export default function Login() {
const router = useRouter();
useEffect(() => {
router.replace('/i/flow/login');
}, [router]);
return <Main />;
}
router.replace() 호출을 useEffect로 감싸면 컴포넌트가 마운트 된 이후에 한 번만 실행되어 정상적으로 리다이렉트 된다.
🤔 고민
그래 안되는 이유는 알겠는데.. 왜 강의 코드는 되고 나는 안 되는 건지는 모르겠다.
package.json을 확인해보면 강의 코드는 Next 14/React 18 버전이고, 내 코드는 Next 15.3.4/React 19 버전이다.
버전 차이일까?? 버전 말고는 진짜 똑같다. 내가 뭘 잘못 쳤나 해서 강의 코드의 src 폴더를 내 프로젝트에 복붙 했는데도 여전했다..
원인을 생각해보면 강의 코드에서도 안 돼야 하는 거 아닌가 싶은데 흠..
Next.js에서 띄운 에러를 구글에 검색해보니 같은 에러를 겪은 사람들 모두 useEffect로 감싸서 해결했다.
내 고민의 답을 검색으로 찾지 못해서 ChatGPT한테도 물어봤는데
1. 이전 버전에서는 router.place()가 hydration 이전에는 무시되거나 한 번만 반영되었을 것이다.
2. 라우터 트리 상태 패치가 지연 적용(lazy) 되었을 것이다.
Next.js 15에서 App Router는 applyRouterStatePatchToTree()라는 함수를 통해 hydration 중에도 라우터 상태를 직접 패치하게 되어 초기 렌더링 시 router.replace() -> 즉시 navigation 처리하여 문제가 발생한 것이다.
라는 답을 줬다.
실제로 그런 함수가 있긴 하다..
'WEB > error' 카테고리의 다른 글
[TanStack Query] Type 'string[]' has no properties in common with type 'InvalidateQueryFilters'.ts(2559) (0) | 2024.11.15 |
---|---|
[React] svgr 세팅 - Duplicate identifier 'src'. (0) | 2024.11.14 |
[Next.js] React Hydration Error (0) | 2024.10.21 |
[html] svg 높이 설정 에러 (0) | 2024.10.21 |