Nextjs14 Sever component rendering

HughKim·2024년 6월 12일
0

Nextjs14

목록 보기
4/6
post-thumbnail

참고문서 NEXTJS DOC

React Server Component(RSC)의 진행 방식

  • 서버에서 요청이 들어오면 RSC Payload를 생성합니다.
  • RSC Payload와 클라이언트 컴포넌트의 자바스크립트 인스트럭션을 활용하여 실제 HTML을 생성합니다.
  • 클라이언트에서 생성된 HTML을 응답받으면, 먼저 pre rendering이 진행됩니다.
  • 이후 RSC Payload가 생성되면 그 정보를 바탕으로 클라이언트에서 reconcile 단계가 진행됩니다.
  • reconcile 단계가 클라이언트에서 진행되는 이유는 클라이언트가 가지는 트리 구조에 빈 공간(placeholder)이 있기 때문에 그 공간을 채우는 과정이기 때문입니다.
  • 이후 서버 컴포넌트와 클라이언트 컴포넌트가 hydrate되고, HTML에 React를 끼얹어 상호작용이 가능해집니다.

    자료출처 : https://www.smashingmagazine.com/2024/05/forensics-react-server-components/

Next.js에서의 서버 컴포넌트 rendering 진행 순서

  • Next.js는 서버에서 React의 API를 활용하여 렌더링을 진행합니다.
    렌더링 작업은 개별 경로의 segment와 Suspense 경계에 따라 chunk로 분할됩니다.

  • React는 서버 컴포넌트를 RSC Payload라는 특수 데이터 형식으로 렌더링합니다.

  • RSC Payload
    - 서버 컴포넌트의 렌더링된 결과

    • 클라이언트 컴포넌트가 렌더링되어야 할 위치의 자리 표시
    • 해당 JavaScript 파일에 대한 참조
    • 서버 컴포넌트에서 클라이언트 컴포넌트로 전달된 모든 props가 포함됩니다.
  • Next.js는 RSC Payload와 클라이언트 컴포넌트 JavaScript 지침을 사용하여 서버에서 HTML을 렌더링합니다.

  • 클라이언트에서 HTML은 초기 페이지 로드에만 사용되며, 빠르고 비대화형적인 경로 preview를 즉시 표시합니다.

  • RSC Payload는 클라이언트와 서버 컴포넌트 트리를 조화시키고 DOM을 업데이트하는 데 사용됩니다.

  • JavaScript 지침은 클라이언트 컴포넌트를 수화하고 애플리케이션을 대화형으로 만드는 데 사용됩니다.
    이상으로 React Server Component(RSC)와 Next.js에서의 서버 컴포넌트 렌더링 과정을 정리해 보았습니다.

자료출처 : https://saengmotmi.netlify.app/react/what-is-rsc/

서버 컴포넌트

const ServerComponent = () => {
	// 이벤트 함수
	const handleClientEvent = () => {
	// client event발생
	console.log('서버에서 발생한 클라이언트 이벤트가 서버에서 처리가 되었습니다!');
   };
return (
	<div onClick={() => handleClientEvent()}>
		서버에서 클릭이벤트가 실행됩니다.
	</div>
	);
};

코드 분석

  • ServerComponent는 서버 측에서 정의된 컴포넌트입니다.
  • handleClientEvent 함수는 클라이언트에서 발생한 이벤트를 서버에서 처리하는 역할을 합니다.
  • 서버 컴포넌트는 onClick 이벤트 핸들러를 통해 클라이언트에서 발생한 이벤트를 받아 처리할 수 있습니다.

서버 컴포넌트 > 클라이언트로 전달되는 RSC Payload

서버 컴포넌트에서 클라이언트로 전달되는 RSC Payload는 서버 측에서 설정하는 합니다.
그래서 일반적으로 React Server Components(RSC) 구현에서는 서버 측 코드에서 이 RSC Payload를 생성하여 클라이언트에 전달하게 됩니다.

// Next.js 서버 측 코드 예시
export const getServerSideProps = () => {
  return {
    props: {
      rscPayload: {
        type: 'RSC_PAYLOAD',
        data: {
          initialState: {
          	// 클라이언트 컴포넌트의 초기 상태 설정
            counter: 0
          },
          eventHandlers: {
          	// 클라이언트에서 발생한 이벤트에 대한 핸들러 설정
            onClick: 'handleServerEvent'
          }
        }
      }
    }
  };
};

코드 분석

  • 서버 컴포넌트에서 클라이언트로 전달되는 데이터 구조입니다.
  • initialState에는 클라이언트 컴포넌트의 초기 상태 정보가 포함되어 있습니다.
  • eventHandlers에는 클라이언트에서 발생한 이벤트에 대한 핸들러 정보가 포함되어 있습니다.
  • payload를 통해 클라이언트 컴포넌트는 서버에서 전달된 초기 상태와 이벤트 핸들러를 활용할 수 있습니다.

클라이언트 컴포넌트

const ClientComponent = ({ initialState, eventHandlers }) => {
  // 클라이언트에서 이벤트 핸들러 정의
  const handleClientEvent = () => {
    // 클라이언트에서 발생한 이벤트에 대한 처리
    console.log('클라이언트에서 발생한 이벤트가 클라이언트에서 처리가 되었습니다.');
  };

  // 클라이언트에서 이벤트 핸들러 등록됩니다.
  const handleClick = () => {
    if (eventHandlers && eventHandlers.onClick) {
      // 서버에서 전달된 이벤트 핸들러 실행합니다.
      eventHandlers.onClick();
    } else {
      // 서버에서 전달된 이벤트 핸들러가 없는 경우, 클라이언트에서 정의한 핸들러 실행합니다.
      handleClientEvent();
    }
  };

  return (
    <div onClick={handleClick}>
      클라이언트에서 클릭 이벤트가 실행됩니다.
      <p>Counter: {initialState.counter}</p>
    </div>
  );
};

코드 분석

  • ClientComponent는 클라이언트 측에서 정의된 컴포넌트입니다.
  • handleClientEvent 함수는 클라이언트에서 발생한 이벤트를 처리하는 역할을 합니다.
  • handleClick 함수는 클라이언트에서 발생한 이벤트를 처리하는데, 서버에서 전달된 이벤트 핸들러(eventHandlers.onClick)가 있는 경우 해당 핸들러를 실행합니다.
profile
성장에 미쳐버린 Frontend Developer

0개의 댓글