Client Components
ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ
ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ๋ ์๋ฒ์์ ๋ฏธ๋ฆฌ ๋ ๋๋ง๋ ์ํธ์์ฉ์ด ๊ฐ๋ฅํ UI๋ฅผ ์์ฑํ ์ ์๊ฒ ํ๊ณ , ๋ธ๋ผ์ฐ์ ์์ ๋์ํ๋ JavaScript๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ํด์ค๋ค.
์ด ํ์ด์ง๋ ์ด๋ป๊ฒ ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ๊ฐ ๋์ํ๋์ง, ์ด๋ป๊ฒ ๊ทธ๋ค์ด ๋ ๋๋๋์ง, ๊ทธ๋ฆฌ๊ณ ์ธ์ ๊ทธ๊ฒ์ ์ฌ์ฉํด์ผ ํ๋์ง์ ๋ํด ์์๋ณผ ๊ฒ์ด๋ค.
Benefits of Client Rendering
ํด๋ผ์ด์ธํธ ๋ ๋๋ง์ ์ด์
ํด๋ผ์ด์ธํธ์ธก์์ ๋ ๋๋ง ์์ ์ ํ๋ ๊ฒ์ ๋ค์๊ณผ ๊ฐ์ 2๊ฐ์ง ์ด์ ์ ๊ฐ์ง๋ค.
- Interactivity (์ํธ์์ฉ): ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ๋ ์ํ(state), ํจ๊ณผ(effects), ์ด๋ฒคํธ ๋ฆฌ์ค๋(event listeners)๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ํด์ค๋ค. ๊ทธ๊ฒ์ ์ ์ ์๊ฒ ์ฆ๊ฐ์ ์ธ ํผ๋๋ฐฑ์ ์ ๊ณตํ๊ณ , UI๋ฅผ ์ ๋ฐ์ดํธํ ์ ์๋ค๋ ์๋ฏธ์ด๋ค.
- Browser APIs (๋ธ๋ผ์ฐ์ API): ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ๋
geolocation
,localStorage
์ ๊ฐ์ ๋ธ๋ผ์ฐ์ API์ ๋ํ ์ ๊ทผ์ด ๊ฐ๋ฅํ๋ค.
Using Client Components in Next.js
NextJS์์ ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ ์ฌ์ฉํ๊ธฐ
ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์ "use client"
๋ฅผ ํ์ผ์ ์ต์๋จ, ๊ทธ๋ฌ๋๊น imports ์์ ์์ฑํด์ผ ํ๋ค.
"use client"
๋ ์๋ฒ์ ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ ๋ชจ๋ ์ฌ์ด์ ๊ฒฝ๊ณ๋ฅผ ์ ์ธํ๋ค.
์ด๊ฒ์ ํ์ผ์ "use client"
๋ฅผ ์ ์ํจ์ผ๋ก์จ ํด๋น ํ์ผ ์์์ import๋ ๋ชจ๋ ๋ชจ๋๊ณผ ์์ ์ปดํฌ๋ํธ๋ค์ ํด๋ผ์ด์ธํธ ๋ฒ๋ค์ ํฌํจ๋ ๊ฒ์ผ๋ก ์ฌ๊ฒจ์ง๋ค๋ ๋ป์ด๋ค.
app/counter.tsx
'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"๋ฅผ ์ ์ธํ์ง ์๊ณ ์ค์ฒฉ๋ ์ปดํฌ๋ํธ(toogle.js
)์์์ onClick
๊ณผ useState
๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ ์๋ฌ๋ฅผ ๋ฐ์์ํจ๋ค๋ ๊ฒ์ ๋ณด์ฌ์ค๋ค.
App Router๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ชจ๋ ์ปดํฌ๋ํธ๋ฅผ ์ด๋ฌํ API๋ค์ ์ฌ์ฉํ์ง ๋ชปํ๋ ์๋ฒ ์ปดํฌ๋ํธ๋ก ์๊ฐํ๊ธฐ ๋๋ฌธ์ด๋ค.toggle.js
์ "use client"
๋ฅผ ์ ์ธํ๋ ๊ฒ์ ์ด๋ฌํ API๋ค์ ์ฌ์ฉํ ์ ์๋ ํด๋ผ์ด์ธํธ ๋ฐ์ด๋๋ฆฌ ์์ ๋ค์ด๊ฐ๊ฒ ๋ค๊ณ ๋ฆฌ์กํธ์๊ฒ ๋งํ๋ ๊ฒ์ด๋ค.
์ฌ๋ฌ๊ฐ์ use client
๋ฅผ ์ํธ๋ฆฌ ํฌ์ธํธ์ ์ ์ธํ๋ ๊ฒ
๋ฆฌ์กํธ ์ปดํฌ๋ํธ ํธ๋ฆฌ์ ์ํธ๋ฆฌ ํฌ์ธํธ๋ค์ ์ฌ๋ฌ๊ฐ์ 'use client'๋ฅผ ์ ์ธํ ์ ์๋ค.
์ด๊ฒ์ ๋น์ ์ ์ ํ๋ฆฌ์ผ์ด์
์ ์ฌ๋ฌ๊ฐ์ ํด๋ผ์ด์ธํธ ๋ฒ๋ค๋ก ๋ถํ ํ ์ ์๊ฒ ํด์ค๋ค.
๊ทธ๋ฌ๋ "use client"
๋ ํด๋ผ์ด์ธํธ์ธก์์ ๋ ๋๋์ด์ผ ํ๋ ๋ชจ๋ ์ปดํฌ๋ํธ์ ์ ์ธ๋ ํ์๋ ์๋ค.
ํ๋ฒ ๋ฐ์ด๋๋ฆฌ๋ฅผ ์ ์ํ๋ฉด, ํด๋น ๋ฐ์ด๋๋ฆฌ ์์ ์๋ ๋ชจ๋ ์์ ์ปดํฌ๋ํธ์ import๋ ๋ชจ๋๋ค์ ํด๋ผ์ด์ธํธ ๋ฒ๋ค์ ํฌํจ๋ ๊ฒ์ผ๋ก ์ฌ๊ฒจ์ง๋ค.
How are Client Components Rendered?
์ด๋ป๊ฒ ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋์ด ์ง๋์ง?
NestJS์์ ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ๋ ์์ฒญ์ด ์ ์ฒด ํ์ด์ง ๋ก๋(์ ํ๋ฆฌ์ผ์ด์ ์ ์ฒ์ ๋ฐฉ๋ฌธํ๊ฑฐ๋, ๋ธ๋ผ์ฐ์ ์๋ก๊ณ ์นจ์ผ๋ก ์ธํ ํ์ด์ง ๋ฆฌ๋ก๋)์ ์ผ๋ถ์ธ์ง ๋๋ ์ดํ์ ํ์ ์ธ์ง์ ๋ฐ๋ผ ๋ค๋ฅด๊ฒ ๋ ๋๋๋ค.
Full page load
์ด๊ธฐ ํ์ด์ง ๋ก๋๋ฅผ ์ต์ ํํ๊ธฐ ์ํด์, NestJS๋ ํด๋ผ์ด์ธํธ, ์๋ฒ ์ปดํฌ๋ํธ ๋ชจ๋์ ๋ํ ์ ์ HTML ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ฅผ ์๋ฒ์์ ๋ ๋ํ๊ธฐ ์ํด React์ API๋ฅผ ์ฌ์ฉํ ๊ฒ์ด๋ค.
์ด๊ฒ์ ์ฌ์ฉ์๊ฐ ์ ํ๋ฆฌ์ผ์ด์
์ ์ฒ์ ๋ฐฉ๋ฌธํ์ ๋, ๊ทธ๋ค์ด ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ JavaScript ๋ฒ๋ค์ ๋ค์ด๋ก๋ํ๊ณ , ํ์ฑํ๊ณ , ์คํํ๋ ๊ฒ์ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ํ์ด์ง์ ๋ด์ฉ์ ์ฆ๊ฐ์ ์ผ๋ก ๋ณด๊ฒ๋๋ค๋ ๊ฒ์ ์๋ฏธํ๋ค.
์๋ฒ์์๋:
- ๋ฆฌ์กํธ๋ ์๋ฒ ์ปดํฌ๋ํธ๋ฅผ React Server Component Payload(RSC Payload)๋ผ ๋ถ๋ฆฌ๋ ํน์ํ ํํ์ ๋ฐ์ดํฐ๋ก ๋ ๋ํ๋ค. ๊ทธ๋ฆฌ๊ณ ์ด๊ฒ์ ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ์ ๋ํ ์ฐธ์กฐ๋ฅผ ํฌํจํ๋ค.
- NextJS๋ ์๋ฒ์์ HTML์ ๋ ๋ํ๊ธฐ ์ํด RSC Payload์ ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ์ JavaScript ๋ช ๋ น์ด๋ค์ ์ฌ์ฉํ๋ค.
๊ทธ๋ฐ ๋ค์, ํด๋ผ์ด์ธํธ์์๋:
- ์๋ฒ์์ ๋ ๋ํ HTML์ ์ํธ์์ฉ์ด ๋์ง ์๋ ์ด๊ธฐ์ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ฅผ ์ฆ๊ฐ์ ์ผ๋ก ๋ณด์ฌ์ฃผ๊ธฐ ์ํด ์ฌ์ฉ๋๋ค.
- RSC Payload๋ ํด๋ผ์ด์ธํธ์ ์๋ฒ ์ปดํฌ๋ํธ ํธ๋ฆฌ๋ฅผ ์กฐํ์ํค๊ณ DOM์ ์ ๋ฐ์ดํธํ๋๋ฐ ์ฌ์ฉ๋๋ค.
- JavaScript ๋ช ๋ น์ ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ๋ฅผ hydrateํ์ฌ, ์ํธ์์ฉ์ด ๊ฐ๋ฅํ UI๋ฅผ ๋ง๋ค๊ธฐ ์ํด ์ฌ์ฉ๋๋ค.
hydration์ด๋?
Hydration์ ์ ์ ์ธ HTML์ ์ํธ์์ฉ์ด ๊ฐ๋ฅํ๋๋ก DOM์ ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผ ๋ถ์ด๋ ๊ณผ์ ์ด๋ค.
ํ๋ฉด ๋ค์์, hydration์ hydrateRoot
๋ฆฌ์กํธ API๋ฅผ ์ฌ์ฉํ์ฌ ์งํ๋๋ค.
Subsequent Navigations
Subsequent Navigation์์๋, ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ๋ ์๋ฒ์์ ๋ ๋๋ HTML ์์ด ์ ์ ์ผ๋ก ํด๋ผ์ด์ธํธ์ธก์์ ๋ ๋๊ฐ ์ด๋ฃจ์ด์ง๋ค.
์ด๊ฒ์ ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ์ JavaScript ๋ฒ๋ค์ด ๋ค์ด๋ก๋๋๊ณ ํ์ฑ๋๋ค๋ ๊ฒ์ ์๋ฏธํ๋ค.
๋ฒ๋ค์ด ์ค๋น๋๋ฉด, ๋ฆฌ์กํธ๋ ํด๋ผ์ด์ธํธ์ ์๋ฒ ์ปดํฌ๋ํธ ํธ๋ฆฌ๋ฅผ ์กฐํ์ํค๊ณ DOM์ ์
๋ฐ์ดํธํ๊ธฐ ์ํด RSC Payload๋ฅผ ์ฌ์ฉํ๋ค.
Going back to the Server Environment
์๋ฒ ํ๊ฒฝ์ผ๋ก ๋์๊ฐ๊ธฐ
๋๋ก๋ "use client"
๋ฅผ ์ฌ์ฉํด์ ํด๋ผ์ด์ธํธ ๋ฐ์ด๋๋ฆฌ๋ฅผ ์ ์ํ ๋ค์์, ์๋ฒ ํ๊ฒฝ์ผ๋ก ๋์๊ฐ๊ณ ์ถ์ ๋๋ ์๋ค.
์๋ฅผ ๋ค์ด, ํด๋ผ์ด์ธํธ ๋ฒ๋ค์ ์ฌ์ด์ฆ๋ฅผ ์ค์ด๊ณ , ์๋ฒ์์ ๋ฐ์ดํฐ๋ฅผ ์์ฒญํ๊ณ , ์๋ฒ์์๋ง ์ฌ์ฉ ๊ฐ๋ฅํ API๋ฅผ ์ฌ์ฉํ๊ณ ์ถ์ ์ ์๋ค.
์ด๋ก ์ ์ผ๋ก ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ ์์ ์ค์ฒฉ๋์ด ์๋๋ผ๋ ํด๋ผ์ด์ธํธ์ ์๋ฒ ์ปดํฌ๋ํธ๋ฅผ ๋ฒ๊ฐ์ ์ฌ์ฉํ๊ณ , ์๋ฒ ์ก์
์ ํตํด์ ์๋ฒ ํ๊ฒฝ์ผ๋ก ๋์๊ฐ ์ ์๋ค.
์์ธํ ๊ฒ์ ํฉ์ฑ ํจํด(Composition Patterns)ํ์ด์ง๋ฅผ ์ฐธ๊ณ ํด๋ผ
์ด๊ฑธ ์ ๋ฆฌํ๋ฉด์ ์๊ฒ๋ ๊ฒ์, ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ๋ ์๋ฒ์์ ๋ฏธ๋ฆฌ ๋ ๋ ๋๋ค๋ ๊ฒ์ด๋ค.
์ง๊ธ๊น์ง๋ ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ๋ ์จ์ ํ ํด๋ผ์ด์ธํธ์ธก์์ ๋ ๋๊ฐ ์ด๋ฃจ์ด์ง๋์ง ์์๋ค.
๋ฌธ๋ ์ด์ ์ "use client"
๋ฅผ ์ฌ์ฉํ์์๋ window
์ ์ ๊ทผํ ์ ์๋ค๋ ์๋ฌ๋ฅผ ๋ฐ์๋ ๊ฒ์ด ๊ธฐ์ต๋ฌ๋ค.
๊ทธ๋๋ ์ด์ฐ์ ์ฐ ๊ตฌ๊ธ๋ง์ ํตํด์ window
๊ฐ undefined์ธ์ง ํ์ธํ๋ ์ฝ๋๋ฅผ ๋ฃ์ด์ ํด๊ฒฐํ์๋๋ฐ, ์๋ฒ์์ ๋ ๋๋๊ธฐ ๋๋ฌธ์ ์ด๋ฌํ ์๋ฌ๊ฐ ๋ฐ์ํ๋ค๋ ๊ฒ์ ์๊ฒ ๋์๋ค.
Reference
https://nextjs.org/docs/app/building-your-application/rendering/client-components
'๊ฐ๋ฐ > NextJS' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
RSC vs SSR (0) | 2024.05.04 |
---|---|
[๊ณต์๋ฌธ์ ๋ฒ์ญ] Composition Pattern (2) | 2024.03.22 |
[๊ณต์๋ฌธ์ ๋ฒ์ญ] NextJS ์๋ฒ ์ปดํฌ๋ํธ (1) | 2024.03.20 |