Next.js

2강 — 서버 컴포넌트

슬라이드 보는 법

→ / Space다음으로
이전으로
↓ / ↑같은 주제 안에서 단계 이동
O전체 슬라이드 한눈에 보기
F전체화면

아래쪽 화살표가 보이면 그 주제는 단계별로 이어집니다

1강 복습

폴더= 주소
page.js화면
layout.js공통 틀

오늘은 그 코드가 어디서 도는지 배웁니다

오늘 끝나면 할 수 있는 것

  • 코드가 서버에서 도는지 브라우저에서 도는지 구분한다
  • 언제 'use client' 를 붙일지 안다
  • 서버와 클라이언트를 섞어 쓴다

오늘 배울 것

  • 7. 렌더링이 어디서 일어나는가
  • 8. 서버 컴포넌트
  • 9. 'use client'
  • 10. 경계 다루기
  • 11. 무엇을 어디에

7. 렌더링이 어디서 일어나는가

React 앱이 화면에 뜨기까지

7. 렌더링이 어디서 React

            
              <div id="root"></div>
              <script src="/bundle.js"></script>
            
          

(흰 화면)

검색엔진은 이 페이지에서 뭘 볼까요?

7. 렌더링이 어디서 두 방식

CSR

브라우저가 그린다

첫 화면이 늦다
SSR

서버가 그려서 보낸다

바로 보인다

7. 렌더링이 어디서 Next

            
              <h1>안녕하세요</h1>
              <p>이미 내용이 들어 있다</p>
            
          

안녕하세요

이미 내용이 들어 있다

8. 서버 컴포넌트

Next의 컴포넌트는 기본이 서버

8. 서버 컴포넌트

            app/page.js
            
              export default function Page() {
                console.log("어디에 찍힐까?");
                return <h1>안녕</h1>;
              }
            
          
어디에 찍힐까?

이 console.log는 어디에 찍힐까요?

8. 서버 컴포넌트

  • 아무 표시가 없으면 서버 컴포넌트
  • 서버에서 실행되고 결과 HTML만 브라우저로 간다
  • 컴포넌트 코드 자체는 브라우저로 안 간다

8. 서버 컴포넌트 async

            
              export default async function Page() {
                const res = await fetch(
                  'https://api.example.com/posts'
                );
                const posts = await res.json();

                return <PostList posts={posts} />;
              }
            
          
  • 첫 번째 글
  • 두 번째 글

8. 서버 컴포넌트 할 수 없는 일

            
              export default function Page() {
                const [count, setCount] = useState(0);
                return <button onClick={...}>{count}</button>;
              }
            
          
useState only works in
Client Components

서버 컴포넌트에서 useState를 쓰면?

9. 'use client'

브라우저에서 돌게 하려면

9. 'use client'

            app/counter.js
            
              'use client';

              import { useState } from 'react';

              export default function Counter() {
                const [count, setCount] = useState(0);
                return <button onClick={() => setCount(count + 1)}>
                  {count}
                </button>;
              }
            
          

9. 'use client' 언제 붙이나

  • useState, useEffect 같은 훅
  • onClick 같은 이벤트
  • window, localStorage

이 중 하나라도 필요하면 'use client'

9. 'use client' 남용

            
              'use client';   // 페이지 전체에 붙임

              export default function Page() {
                return (
                  <>
                    <BigArticle />   {/* 안 움직이는 글 */}
                    <Counter />      {/* 버튼 하나 */}
                  </>
                );
              }
            
          
글까지 전부 브라우저로 간다
번들이 커진다

버튼 하나 때문에 페이지 전체를 클라이언트로 만들면?

10. 경계 다루기

서버와 클라이언트를 섞어 쓰려면

10. 경계 다루기 역할 나누기

서버 컴포넌트

  • 데이터 가져오기
  • 비밀 키 사용
  • 큰 라이브러리
  • DB 접근

클라이언트 컴포넌트

  • useState / useEffect
  • onClick 등 이벤트
  • window, localStorage
  • 애니메이션

10. 경계 다루기 props로 전달

            
              // 서버 컴포넌트
              export default async function Page() {
                const posts = await getPosts();
                return <LikeButton posts={posts} />;
              }
            
          
서버 → 클라이언트로
데이터를 내려보낼 수 있다

10. 경계 다루기 함수는 안 됨

            
              <LikeButton onLike={() => save()} />
            
          
Functions cannot be passed
to Client Components

서버에서 클라이언트로 함수를 넘기면?

10. 경계 다루기 children 패턴

            
              // 클라이언트 컴포넌트 안에서
              import ServerThing from './ServerThing';   // 안 됨

              // 대신 children으로 받는다
              <ClientWrapper>
                <ServerThing />
              </ClientWrapper>
            
          
children으로 넘기면
서버 컴포넌트가 유지된다

11. 무엇을 어디에

판단하는 기준

11. 무엇을 어디에

  • 일단 전부 서버 컴포넌트로 만든다
  • 훅이나 이벤트가 필요해지면 그때 쪼갠다
  • 'use client'잎사귀에 붙인다

뿌리에 붙이면 그 아래가 전부 클라이언트가 된다

11. 무엇을 어디에 React와 비교

React

전부 브라우저

고민할 게 없었다
Next.js

기본은 서버

필요할 때만 클라이언트

정리

오늘 배운 것

한눈에

기본값서버 컴포넌트
서버에서데이터, 비밀 키, 큰 라이브러리
'use client'훅 · 이벤트 · window가 필요할 때
경계props는 되고 함수는 안 된다
원칙잎사귀에만 붙인다

실습

직접 해봅시다

실습 과제

  1. page.js에 console.log 를 넣고 어디 찍히는지 확인
  2. 버튼 컴포넌트만 'use client' 로 분리하기
  3. 서버에서 받은 데이터를 그 버튼에 props로 넘기기

더 볼 것

3강에서는 데이터를 가져옵니다