nextjs14의 서버와 클라이언트 컴포넌트

choi seung-i·2024년 7월 5일
0

공부로그

목록 보기
21/25

next14에서 로직을 분리하면서 혼돈을 겪고있는 상황에 머릿속 정리겸 공부
내 언어로 풀어서 기록하며 기본부터 정리해보자...
(틀린건 댓글로 알려주시면 감사하겠습니다)

클라이언트 컴포넌트

  • "use client" 명시해준 컴포넌트
  • 뷰를 그리고 데이터 호출을 통해 추가 뷰를 그려야 한다면, 네트워크 워터폴이 생김으로 컴포넌트의 응답 지연되어 사용자 경험이 저하됨
  • 정말 클라이언트에서만 실행을 하고 싶다면??
    클라이언트컴포넌트를 import할 때 dynamic import를 사용하며, ssr을 false로 꺼준다.
    그럼 pre-rendering을 비활성화 할 수 있다.
    const ComponentC = dynamic(() => import('../components/C'), { ssr: false })

서버 컴포넌트

  • page.tsx 또는 일반 컴포넌트 생성시 기본이 서버컴포넌트임(위처럼 클라이언트 명시해주거나 클라이언트 컴포넌트 내부에 위치하지 않는 다면)
  • 자동 코드 분할을 지원하여 번들 크기를 줄여 앱의 성능을 향상시킴
  • 서버에서 뷰 생성과 백엔드 접근이 가능해 데이터 호출을 한번에 해서 클라이언트로 넘겨주기 때문에(=SSR과 함께) 네트워크 워터폴을 피할 수 있다.
    -> 서버에서는 모양(HTML)만 만들어 보내주고(=pre-rendering), 상호작용을 할 수 있도록 영혼을 불어넣어준다.(=hydration)

pre-rendering : 사전렌더링
SSR : 서버에서 HTML을 클라이언트로 보내고, 이후에 클라이언트사이드 자바스크립트를 다운로드하여 상호작용 할 수 있도록 hydration 시켜주는 것 (초기 페이지를 빠르게 로드하는데 유용하게 해줌)

RSC(서버컴포넌트)와 SSR 둘다 서버라는 말을 사용하기때문에 같다고 생각할 수 있지만, "서버에서 동작한다" 는 것만 같고 역할이나 행동이 다름. (참고글에 자세한 설명있기에 여기선 생략..)


어떻게 나누는가?

hooks나 onClick과 같은 이벤트를 사용 할 경우(=hydration을 해 줄 것들) 클라이언트 컴포넌트를 분리해주어 서버와 클라이언트 컴포넌트를 나눠줄 수 있다.

⭕️ 서버컴포넌트 내에 클라이언트컴포넌트를 사용할 수 있다.

const ServerCom = () => {
  // 여기서 서버 로직 사용 가능
  
	return <ClientCom />
}

🔺 클라이언트컴포넌트 내에 서버컴포넌트를 사용할 수 있다.
-> 하지만 그 서버 컴포넌트는 클라이언트컴포넌트로 동작한다.

const ClientCom = () => {
  const [val, setVal] = useState("");
  
  const handleConfirm = () => {
    setVal("textttt")
  }
	return <>
      	<ServerCom val={val}/>
      	<button onClick={handleConfirm}>확인</button>
      </>
}

⭕️ 서버컴포넌트를 클라이언트컴포넌트로 감싸서 사용할 수 있다.
-> 부모(page)가 렌더링 되는 시점에 서버컴포넌트가 렌더링 됨으로 서버와 클라이언트 컴포넌트 둘다 의도했던대로 작동한다.

const Page = () => {
  
  const handleConfirm = () => {
    setVal("textttt")
  }
	return <>
      	<ClientCom>
          <ServerCom />
          <div>page.tsx는 서버에용<div>
      	</ClientCom>
      </>
}

⭕️ 클라이언트컴포넌트에서 server action을 사용 할 수 있다.

// ex) action.ts (server action 파일 분리)
"use server"

export const handleSubmit = () => {
  // 뭐시기뭐시기
}
import { handleSubmit } from "./action.ts"

const ClientCom = () => {
  
	return <>
            <form action={handleSubmit}>
              <input name="id" />
              <input name="pw"/>
              <button type="submit">확인</button>
            </form>
      </>
}

[reference]
https://velog.io/@ssonnni/Next.js14-03.Hydration
https://nextjs.org/docs/app/building-your-application/optimizing/lazy-loading#nextdynamic
https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations#pending-states
https://www.freecodecamp.org/korean/news/how-to-use-react-server-components/
https://velog.io/@2ast/React-%EC%84%9C%EB%B2%84-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8React-Server-Component%EC%97%90-%EB%8C%80%ED%95%9C-%EA%B3%A0%EC%B0%B0

profile
Front-end

0개의 댓글