next.js에서 Context Api로 각기 다른 tap에서 화면을 다르게 렌더링하는 방법을 간단하게 적어보겠습니다.
먼저 전체 코드는 다음과 같습니다.
긴글 읽으시기 불편하신 분들은 코드만 참고하셔도 좋습니다!!
// page.tsx
export default function Home() {
return (
<main className={style.main}>
<TabProvider>
<Tab />
</TabProvider>
</main>
);
}
// TabProvider.tsx
"use client";
import { createContext, ReactNode, useState } from "react";
export const TabContext = createContext({
tab: "rec",
setTab: (value: "rec" | "fol") => {},
});
type Props = { children: ReactNode };
export default function TabProvider({ children }: Props) {
const [tab, setTab] = useState("rec");
return (
<TabContext.Provider value={{ tab, setTab }}>
{children}
</TabContext.Provider>
);
}
// Tab
"use client";
import style from "./tab.module.css";
import { useState } from "react";
export default function Tab() {
const [tab, setTab] = useState("rec");
const onClickRec = () => {
setTab("rec");
};
const onClickFol = () => {
setTab("fol");
};
return (
<div className={style.homeFixed}>
<div className={style.homeText}>홈</div>
<div className={style.homeTab}>
<div onClick={onClickRec}>
추천
<div className={style.tabIndicator} hidden={tab === "fol"}></div>
</div>
<div onClick={onClickFol}>
팔로우 중
<div className={style.tabIndicator} hidden={tab === "rec"}></div>
</div>
</div>
</div>
);
}
next는 서버 컴포넌트와 클라이언트 컴포넌트로 나뉘어 있습니다.
디폴트는 서버 컴포넌트입니다. 만약에 화면에 동적인 움직임을 주고 싶으면 클라이언트 컴포넌트를 사용해야 하는데 매우 간단하게 파일 최상단에 "use client" 한줄 적어주시면 됩니다.
app router에서는 page 파일은 무조건 서버 컴포넌트이기 때문에 만약에 클라이언트 컴포넌트 기능을 사용하기 원하신다면 무조건 별도로 분리해서 임포트 하는 방법으로 코드를 작성하셔야 합니다!!
클라이언트 컴포넌트의 자식 컴포넌트들은 자연스럽게 클라이언트 컴포넌트가 됩니다. 클라이언트 컴포넌트는 개발자 도구에서 네트워크 탭에서 미리보기를 통해 html 파일을 볼 수 있고 이는 구글 검색에서 우위를 점할 수 있습니다.
"검색 엔진 최적화"와 "빠른 페이지 렌더링"
서버 컴포넌트의 장점으로는 검색 엔진 최적화와 빠른 페이지 랜더링이 있습니다. 단점으로는 서버에 대한 이해가 필요하고 프론트 환경과 다르기에 브라우저 객체 접근에 제한이 생길 수 있습니다.
다음은 캡틴판교님의 설명입니다.
서버 사이드 렌더링을 쓰는 목적은 크게 "검색 엔진 최적화"와 "빠른 페이지 렌더링"입니다. 검색 엔진 최적화란 구글, 네이버와 같은 검색 사이트에서 검색했을 때 결과가 사용자에게 많이 노출될 수 있도록 최적화 하는 기법입니다. 특히, SNS에서 링크를 공유했을 때 해당 웹 사이트의 정보를 이미지와 설명으로 표시해주는 OG(Open Graph) Tag를 페이지 별로 적용하기 위해서는 서버 사이드 렌더링이 효율적입니다.
또한, 서버 사이드 렌더링은 빈 HTML 페이지를 받아 브라우저에서 그리는 클라이언트 사이드 렌더링과 다르게 서버에서 미리 그려서 브라우저로 보내주기 때문에 페이지를 그리는 시간을 단축할 수 있습니다. 사용자 입장에서는 화면에 유의미한 정보가 표시되는 시간이 빨라지는 것이죠.
이렇게만 보면 서버 사이드 렌더링을 하는게 좋겠네 라고 생각하실 수 있지만 시작하기 전에 주의해야 할 점이 있습니다. 서버 사이드 렌더링은 Node.js 웹 애플리케이션 실행 방법을 알아야하고 서버쪽 환경 구성과 함께 클라이언트, 서버 빌드에 대한 이해가 필요합니다. 따라서, 프런트엔드 개발 입문자 입장에서는 쉽지 않은 진입 장벽이 존재합니다.
또한, Node.js 환경에서 실행되기 때문에 브라우저 관련 API를 다룰 때 주의해야 합니다. 뷰 싱글 페이지 애플리케이션의 라이프사이클 훅과는 다른 환경(브라우저가 아닌 Node.js)에서 동작하기 때문에 beforeCreate와 created에서 window나 document와 같은 브라우저 객체에 접근할 수 없습니다.
긴 글 읽어주셔서 감사합니다!!