FBI WARRING
문제의 흐름에 따라 공부를 찾다보니 글쓴이가 지금 무슨 짓을 하는지 모를 수 있음
이쁘게 봐주시고 잘못된 부분이 있다면 언제든 회초리 환영입니다.
NextJS를 사용하다보니 문뜩 layout.js에서 "use client"를 사용하면 그의 자식 요소들이 모두 클라이언트 컴포넌트가
되는 것인지 궁금증이 발생했다.
일단 직접 테스트를 진행해봤다. 테스트 방식으론 Root Layout에게 "use client"를 주고 page에게는 따로 주지 않는 상태에서 콘솔을 각각 주는 방법으로 했을 때, 만약 page의 콘솔이 먼저 나온다면 전파가 안되는 것이고 layout이 먼저 나온다면
전파가 되는 것이라고 생각했다.
"use client";
export default function RootLayout({ children }) {
console.log("layout");
return (
<html lang="en">
<body>{children}</body>
</html>
);
}
##################################################
export default function Home() {
console.log("page");
return <div></div>;
}
테스트를 했을 때 page > layout 순으로 콘솔이 출력되었다. 이렇게만 봤을 때 "use client"가 전파되지 않는 거라고
생각이 될 수 있지만 layout에게 "use client"를 지우고 콘솔을 확인 했을 때도 동일하게 page > layout 순으로
출력이 되었다.
먼가 잘못되었다!
아무래도 랜더링 순서가 내가 생각했던 방법이 아니었다.
단순하게 layout이 page 파일보다 먼저 실행이 된다고 생각했는데, 그게 아니고 복잡한 방식으로 실행되는 것 같아서
먼저 둘의 실행 순서를 알아보았다.
이상하다 생각 했던 이유가 layout과 page의 실행 방식 차이였다.
page 단위에서는 컴포넌트가 렌더링 되는 시점에 내부 코드들이 전부 실행되지만 layout에서는 자식 요소들의 렌더링이
완료되야지 본인의 렌더링이 완료된다.
정리하자면
다음과 같다.
layout은 자식 요소들이 전부 렌더링이 완료되어야 렌더링이 내부 처리가 완료되는데, page는 본인 작업과 함께 진행된다.
다시 "use client"를 사용했을 때 전파에 대해서 알아보기 시작했다.
일단 구글에 검색했을 때 가장 많이 나오는 이야기가 root layout에서는 "use client"를 통해서 클라이언트 컴포넌트를
만들 수 없다는 이야기가 많았다.
The root layout is a Server Component by default and can not be set to a Client Component.
하지만 공식 문서를 봤을 땐 해당 내용이 없었다.
일반 layout은 클라이언트 컴포넌트로 변경할 수 있다는 이야기 뿐....!
쭈욱 로그를 살펴보니 14.1.1-canary.15 버전부터 변경됐었다.
이후 버전에서는 root layout에서도 'use client'를 사용해도 문제가 없는 것으로 보인다.
그렇다면 다시 돌아가서 클라이언트 컴포넌트는 어떻게 전파가 되는 것일까?
부모 컴포넌트가 클라이언트 컴포넌트인테 children으로 서버 컴포넌트를 넣어줬을 때, 서버 컴포넌트로 동작했다:
"use client"
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
</body>
</html>
);
}
#############################################
import axios from "axios";
async function getData() {
const res = await axios.get("https://jsonplaceholder.typicode.com/users");
return res;
}
export default async function Home() {
const { data } = await getData();
return data.map(({ name, email }) => (
// ...
));
}
RootLayout이 클라이언트 컴포넌트인데, page 파일에서는 ssr로 데이터를 제대로 불러 오는 것을 확인할 수 있었다.
이유를 찾아보니 공식 문서에 해당 내용이 설명되어 있었다...!
children으로 넘겨주면 부모와 자식이 독립적으로 실행된다고 설명이 되어 있다.
Next.JS에 대해서 정확한 이해 없이 바로 사용하다보니 발생한 문제였다.
'Next.js > 실험실' 카테고리의 다른 글
not-found와 layout (1) | 2024.06.19 |
---|---|
포괄 검색어로 홈페이지 노출시키기 (2) | 2024.06.09 |
NextJS Pages Router에서의 Styled Components (1) | 2024.05.30 |
홈페이지 상단에 노출시키기 (7) | 2024.05.11 |
[Next.js] Infinity Scroll (0) | 2023.03.06 |