Next JS에서 컴포넌트의 구성(Server , Client Component)

Mincho·2023년 5월 24일
4

[NextJs]

목록 보기
2/12

🔴 NextJs에서의 컴포넌트

NextJs에서는 13버전이 업데이트 되면서부터 모든 컴포넌트가 기본적으로 서버 컴포넌트다. NextJs에서는 서버 컴포넌트와 클라이언트 컴포넌트가 있으며, 이를 잘 이해하고 사용하는 것이 중요할 것 것아 정리하게 되었다.

NextJs공식문서

 위와 같이 NextJs에서 서버 컴포넌트와 클라이언트 컴포넌트의 차이점을 구분해주고 있다.



🟠 서버 컴포넌트 -> 클라이언트 컴포넌트

서버 컴포넌트는 서버에서 실행되는 React 컴포넌트라고 볼 수 있다. 이러한 컴포넌트의 특징은 서버 측에서 렌더링되어 초기 HTML을 제공하여 렌더링 시 필요한 변하지 않는 초기 데이터를 미리 세팅하는 것에 큰 도움을 줄 수 있다.

서버 컴포넌트를 사용할 때 주의 할 점이 있다.

import React, { useState } from "react";
import styles from "../../app/page.module.scss";

const MainVideo = () => {
  const [data, setData] = useState();
  return (
    <video autoPlay loop muted className={styles.mainVideo}>
      <source src="/videos/heart.mp4" type="video/mp4"></source>
    </video>
  );
};

export default MainVideo;

 위의 코드와 에러에서 확인할 수 있듯이 NextJs에서는 기본적으로 컴포넌트를 만들때 서버컴포넌트로 동작된다. 도입부에 서버 컴포넌트와 클라이언트 컴포넌트의 차이를 설명한 공식문서에서 확인할 수 있듯, 서버 컴포넌트에서는 react lifeCycle을 가능하게 하는 useState, useEffect같은 함수를 사용하지 못한다.

 그렇기 때문에 클라이언트 컴포넌트라 명시를 해줘야한다.
클라이언트 컴포넌트라 명시하는 방법은 어렵지 않다. 코드 맨위에 "use client"라고 작성하면 된다.

  life cycle함수 외에 onClick, onChange같은 이벤트 함수 또 Css-in Js 스타일링도 제한된다. 그러므로 클라이언트 컴포넌트와 서버 컴포넌트를 통합하며 구분도 해주는 것이 좋다.



🟡 컴포넌트 구성은 어떻게 하는게 현명할까??

//. app/page.tsx
import styles from "./page.module.scss";
import IdolSection from "@/component/mainPage/IdolSection";
import MainVideo from "@/component/mainPage/MainVideo";
import RandomSchedule from "@/component/mainPage/RandomSchedule";
import { getIdolList, getIdolSchedules } from "@/utils/axios/AxiosSetting";

export default async function Home() {
  const { schedulesData, idolData } = await getData();

  return (
    <>
      <MainVideo />
      <div className={styles.home}>
        <div className={styles.homeContainer}>
          <RandomSchedule schedulesData={schedulesData} />
          <IdolSection idolData={idolData} />
        </div>
      </div>
    </>
  );
}

async function getData() {
  const schedulesData = await getIdolSchedules();
  const idolData = await getIdolList();

  return { schedulesData, idolData };
}

 위의 코드는 mainPage(link = "/")에 보여질 컴포넌트이다. 기본적으로 page는 서버 컴포넌트로 구성하고 이 페이지에 보여줄 컴포넌트들을 return으로 넣어 놓았다.

 구성 된 컴포넌트에서 주목해야할 점이 있는데, 서버 컴포넌트는 서버에서 렌더링이 되어지기 때문에 미리 보여주고 데이터 로딩 없이 보여줄 데이터를 이 곳에 가져와 준다.

async function getData() {
  const schedulesData = await getIdolSchedules();
  const idolData = await getIdolList();

  return { schedulesData, idolData };
}

 getData함수를 이용해 api데이터를 가져온다.(fetch를 이용) 그렇게 하여 가져온 데이터를 각각 <RandomSchedule>컴포넌트와 <IdolSection>컴포넌트에 넣어주었다.



🟢 클라이언트 컴포넌트를 확인해보자

"use client";
import React, { useState } from "react";
import styles from "../../app/page.module.scss";
import Link from "next/link";
import { IdolData } from "@/app/admin/[...category]/interface";

interface IdolSectionProps {
  idolData: IdolData[];
}

const IdolSection = ({ idolData }: IdolSectionProps) => {
  const [isModal, setIsModal] = useState(false);
  const slideImage = idolData?.slice(0, 30);

  return (
    <>
      {isModal ? <div>Modal</div> : null}
      <button onClick={() => setIsModal(!isModal)}>ON</button>
      <div className={styles.artistSection}>
        <article className={styles.articleContents}>
          <div className={styles.artistFontWrapper}>
            <div className={styles.mainTitle}>
              <p>60팀의 아티스트를</p>
              <p>최애인에서 만나볼 수 있어요</p>
            </div>
            <div className={styles.subTitle}>
              <p>지금 인기있는 아티스트들을 선택하고</p>
              <p>스케줄을 확인해서 나만의 스케줄을 만들어보세요</p>
            </div>
          </div>
          <ul className={styles.artistImageWrapper}>
            {slideImage?.map((data: any) => (
              <li className={styles.artistThumnail} key={data.pk}>
                <Link href={`calendar/${data.pk}`}>
                  <img
                    className={styles.artistImage}
                    src={data.idol_profile}
                    alt="아티스트 이미지"
                  />
                  <h3 className={styles.artistName}>{data.idol_name_kr}</h3>
                  <p className={styles.artistFont}>{data.idol_name_en}</p>
                </Link>
              </li>
            ))}
          </ul>
        </article>
      </div>
    </>
  );
};

export default IdolSection;

};

 다음과 같이 서버컴포넌트에서 받은 데이터를 보여주는 컴포넌트 중 하나인 <IdolSection>컴포넌트를 한번 보자. 정상적으로 서버 컴포넌트에서 데이터를 받아오며 useState를 사용하여 상태 관리까지 가능해졌다.

 또한 정상적으로 데이터를 받아오는 것을 확인할 수 있으며,,

 실제 소스 코드를 볼 때도 서버 측에서 데이터를 받아와서 클라이언트에서 보여주고 있기 때문에 리액트와 달리 데이터가 표시되는 것을 확인할 수 있다. SEO노출에 유리하다!!



👍올바른 피드백은 언제든지 환영입니다~!

profile
사진찍는 개발자.

0개의 댓글