이전 게시글에서, 파일 최상단에 "use client"
를 써주지 않아서 오류가 났던 이유를 찾아보았다.
서버 컴포넌트
와 클라이언트 컴포넌트
에 대해 알아보자.
클라이언트 컴포넌트
는, 버튼 또는 검색창과 같이 사용자와 상호작용하는 작은 UI 들을 클라이언트 단에서 렌더링되는 컴포넌트를 뜻한다.'use client'
import { useState } from 'react'
export default function Counter() {
const [count, setCount] = useState(0)
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
)
}
'use client'
를 파일의 최상단(import 보다 위, 첫 번째 줄)에 입력하면, 하위 구성요소를 포함하여 해당 파일로 가져온 다른 모든 모듈이 클라이언트 번들의 일부로 간주된다.'use client'
를 선언하지 않아도, 진입점에서 한 번만 정의해주면 된다.서버 컴포넌트
란, 말 그대로 서버 부분에서 렌더링 되는 컴포넌트이다.서버 컴포넌트
가 기본이다.!클라이언트 컴포넌트
로 사용하고 싶다면, 'use Client'
를 입력해주면 된다.Client Component
사용 불가async
함수로 정의 가능// **클라이언트 컴포넌트**
"use client";
import { useState, useEffect } from "react";
export default async function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
const [ topics, setTopics ] = useState();
useEffect(() => {
const setPage = async () => {
const { data } = fetch(`http://localhost:9999/topics`);
setTopics(data}
}
setPage();
},[])
return (
<html>
<body>
<ol>
{topics.map((topic: ITopics) => {
return (
<li key={topic.id}>
<Link href={`/read/${topic.id}`}>{topic.title}</Link>
</li>
...
위 클라이언트 컴포넌트
를 서버 컴포넌트
로 바꾸면 아래와 같다.
// **서버 컴포넌트 코드**
export default async function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
const resp = await fetch(`http://localhost:9999/topics`);
const topics = await resp.json();
return (
<html>
<body>
<ol>
{topics.map((topic: ITopics) => {
return (
<li key={topic.id}>
<Link href={`/read/${topic.id}`}>{topic.title}</Link>
</li>
...
onClick
, useState
등 과 같은 클라이언트 컴포넌트
사용이 불가피한 경우를 모든 제외한 경우라고 할 수 있을 것 같다.
즉시 데이터를 fetch
하여 화면에 보여주거나, env
에서 가져오는 API_KEY
등의 보안이 필요한 곳에서 사용하면 된다.
위의 이미지에서 보면, 사용자 상호작용이 잘 일어나지 않는 Navbar, Side bar 등이 서버 컴포넌트
에 해당하고,
onChange
이벤트와 더불어 useState
를 사용해야하는 검색창, 클릭 이벤트가 발생하는 버튼 등이 클라이언트 컴포넌트
에 해당한다.
서버 컴포넌트
에 대해서 알아보다보면, 서버에서 렌더링된다는 점이 SSR
과 유사하다는 것을 알게되는데, 나 또한 이 부분이 궁금하여 알아보았다.
SSR
은 서버에서 렌더링 된 HTML 을 가져오지만,서버 컴포넌트
는 HTML 이 아닌 렌더링 할 트리 객체를 가져온다는 점이다.서버 컴포넌트
, 클라이언트 컴포넌트
로 구성되어 있으며(서버 컴포넌트
안에 클라이언트 컴포넌트가
포함된),