์ด ๊ธ์ ์์ฑ์์ ๊ฒฌํด๋ฅผ ๋ฐํ์ผ๋ก chatgpt์ ๋์์ ๋ฐ์ ์์ฑ๋์์ต๋๋ค.
โ๏ธ React์์ ๋น๋๊ธฐ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃจ๋ ๋ค์ํ ๋ฐฉ์
React๋ state ์ค์ฌ์ UI ํ๋ ์์ํฌ๋ค.
์ฆ, ์ฌ์ฉ์ ์ธํฐํ์ด์ค์ ํ์๋๋ ๋์ ๋ฐ์ดํฐ๋ ๋ชจ๋ state๋ฅผ ํตํด ๊ด๋ฆฌ๋๋ฉฐ, ์ด state๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง๋ค ์ปดํฌ๋ํธ๋ ๋ค์ ๋ ๋๋ง๋๋ค.
๊ทธ๋ ๋ค๋ฉด ์ด๋ฐ ํ๋ฆ ์์์ ๋น๋๊ธฐ ๋ฐ์ดํฐ๋ ์ด๋ป๊ฒ ์ฒ๋ฆฌํด์ผ ํ ๊น?
์๋ฅผ ๋ค์ด ์๋ฒ์์ ์ํ ๋ชฉ๋ก์ ๊ฐ์ ธ์จ๋ค๊ฑฐ๋, ์ธ๋ถ API์์ ๋ ์จ ์ ๋ณด๋ฅผ ๋ฐ์์ค๋ ๋ฑ์ ์์
์ **๋น๋๊ธฐ(Promise ๊ธฐ๋ฐ)**์ด๋ค.
์ด๋ฌํ ๋ฐ์ดํฐ๋ฅผ React์์ ํํํ๊ธฐ ์ํด ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ํจํด์ ๋ค์๊ณผ ๊ฐ๋ค:
ย
๐ useEffect๋ฅผ ํ์ฉํ ๋น๋๊ธฐ ๋ฐ์ดํฐ ๋ก๋ฉ
React์ ๋ํ์ ์ธ ๋น๋๊ธฐ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ๋ฐฉ๋ฒ์ useEffect ํ
์ ์ฌ์ฉํ๋ ๊ฒ์ด๋ค.
'use client'; import { useEffect, useState } from 'react'; import { Product } from '@/libs/types/types'; import { fetchProducts } from '@/libs/fetchProducts'; export function Products() { const [products, setProducts] = useState<Product[]>([]); useEffect(() => { (async () => { const result = await fetchProducts(); setProducts(result); })(); }, []); return ( <ul className="flex flex-col gap-4"> {products.map((product) => ( <li key={product.id} className="border border-green-400"> <strong>{product.title}</strong> </li> ))} </ul> ); }
โ ํ๋ฆ ์์ฝ
- products๋ผ๋ ์ด๊ธฐ ์ํ๊ฐ์ ๋น ๋ฐฐ์ด๋ก ์ค์
- useEffect ์์์ ๋น๋๊ธฐ ๋ฐ์ดํฐ๋ฅผ ํธ์ถ
- setState๋ก ๋ฐ์ดํฐ๋ฅผ ๊ฐฑ์
- ์ปดํฌ๋ํธ๊ฐ ๋ฆฌ๋ ๋๋ง๋์ด ์๋ก์ด ๋ฐ์ดํฐ๊ฐ ํ๋ฉด์ ํ์๋จ
์ด ๋ฐฉ์์ ํด๋ผ์ด์ธํธ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ์ ํต์ ์ธ ํจํด์ด๋ฉฐ, CSR(Client Side Rendering)์์ ์ฃผ๋ก ์ฌ์ฉ๋๋ค.
ย
โ๏ธ ์๋ฒ ์ฌ์ด๋์์ ๋น๋๊ธฐ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ ค๋ฉด?
Next.js๋ Remix์ฒ๋ผ **์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง(SSR)**์ ์ง์ํ๋ ํ๋ ์์ํฌ์์๋
์ด๊ธฐ ๋ ๋๋ง ์์ ๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ HTML์ ์์ฑํด์ผ ํ๋ ์๊ตฌ๊ฐ ์๋ค.
ํ์ง๋ง ์๋ฒ์์๋ useEffect๋ useState๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
(์๋ฒ๋ DOM์ด ์๊ณ , ๋ฆฌ๋ ๋๋ง์ด๋ผ๋ ๊ฐ๋
์์ฒด๊ฐ ์กด์ฌํ์ง ์๊ธฐ ๋๋ฌธ)
๊ทธ๋์ ๋ฑ์ฅํ ๋ฐฉ์์ด ๋ฐ๋ก ๋น๋๊ธฐ ์ปดํฌ๋ํธ๋ค.
ย
๐งฉ ๋น๋๊ธฐ ์ปดํฌ๋ํธ์ Suspense
์ปดํฌ๋ํธ ์์ฒด๋ฅผ ๋น๋๊ธฐ๋ก ๋ง๋ค๊ณ , Suspense๋ฅผ ํ์ฉํด ๋ก๋ฉ ์ํ๋ฅผ ์ฒ๋ฆฌํ๋ ํจํด์ด๋ค.
// โ ์๋ชป๋ ์ฌ์ฉ (ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ์ async ์ฌ์ฉ) 'use client'; import { fetchProducts } from '@/libs/fetchProducts'; export async function Products() { const products = await fetchProducts(); return ( <ul> {products.map((product) => ( <li key={product.id}>{product.title}</li> ))} </ul> ); }
์ด ๋ฐฉ์์ ์๋ชป๋ ์ฌ์ฉ์ด๋ค. async ์ปดํฌ๋ํธ๋ ์๋ฒ์์๋ง ์ฌ์ฉํ ์ ์์ผ๋ฉฐ, ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ์๋ async๋ฅผ ๋ถ์ผ ์ ์๋ค.
โ ์ฌ๋ฐ๋ฅธ ๊ตฌ์กฐ
// ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ 'use client'; import { Product } from '@/libs/types/types'; export function Products({ products }: { products: Product[] }) { return ( <ul> {products.map((product) => ( <li key={product.id}>{product.title}</li> ))} </ul> ); }
// ์๋ฒ ์ปดํฌ๋ํธ import { fetchProducts } from '@/libs/fetchProducts'; import { Products } from './products'; export async function ProductsContainer() { const products = await fetchProducts(); return <Products products={products} />; }
์ด๋ ๊ฒ ์๋ฒ์์ ๋ฐ์ดํฐ๋ฅผ ๋ฏธ๋ฆฌ ๋ฐ์์ ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ์ props๋ก ์ ๋ฌํ๋ฉด, ํด๋ผ์ด์ธํธ๋ useEffect ์์ด ๋ฐ์ดํฐ๋ฅผ ๋ ๋๋งํ ์ ์๋ค.
ํ์ง๋ง ์ด๋ฐ ๋ฐฉ์์ ๋น๋๊ธฐ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃจ๊ธฐ ์ํด ์ปดํฌ๋ํธ ์์ฒด๊ฐ ๋น๋๊ธฐ ์ปดํฌ๋ํธ๊ฐ ๋์ด์ผํ๋ฉฐ, ์ด์ ๋ฐ๋ผ ์ปดํฌ๋ํธ ๊ตฌ์กฐ๊ฐ ๋ถ๋ฆฌ๋์ด์ผ ํ๋ ๋ถํธํจ์ด ๋ฐ๋ฅด๊ธฐ๋ํ๋ค.
ย
๐ก use ํ ์ ๋ฑ์ฅ
React 19์์ use(promise)๋ผ๋ ์๋ก์ด ํ
์ด ์คํ์ ์ผ๋ก ๋์
๋๋ฉฐ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๊ฒ ๋์๋ค.
โ ๊ตฌ์กฐ๋ฅผ ๋จ์ํ๊ฒ
// ์๋ฒ ์ปดํฌ๋ํธ import { fetchProducts } from '@/libs/fetchProducts'; import { Suspense } from 'react'; import { Products } from './products'; export default function Page() { const productsPromise = fetchProducts(); return ( <div> <h1>Use Example</h1> <Suspense fallback={<div>Loading...</div>}> <Products productsPromise={productsPromise} /> </Suspense> </div> ); }
// ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ 'use client'; import { Product } from '@/libs/types/types'; import { use } from 'react'; export function Products({ productsPromise }: { productsPromise: Promise<Product[]> }) { const products = use(productsPromise); return ( <ul> {products.map((product) => ( <li key={product.id}>{product.title}</li> ))} </ul> ); }
์ด์ ๋ ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ์์๋ ์ง์ ๋น๋๊ธฐ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ ์ฌ์ฉํ ์ ์์ผ๋ฉฐ
useEffect๋, ๋ณ๋์ ์๋ฒ ์ปดํฌ๋ํธ๋ ํ์ ์๋ค.
ย
๐ง ๋ง๋ฌด๋ฆฌ
React๋ ์๋ state ์ค์ฌ์ผ๋ก ๋์ํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๊ธฐ ๋๋ฌธ์, ๋น๋๊ธฐ ๋ฐ์ดํฐ์ UI์ ๊ด๊ณ๋ฅผ ์ ์ ๋ฆฌํด๋๋ ๊ฒ์ด ์ค์ํ๋ค.
- useEffect๋ ํด๋ผ์ด์ธํธ์์์ ๋น๋๊ธฐ ๋ฐ์ดํฐ ํจ์นญ์ ์ ํฉ
- ์๋ฒ์์ ๋ฐ์ดํฐ๋ฅผ ํจ์นญํ ๋ ์๋ฒ ์ปดํฌ๋ํธ๋ฅผ ๋ถ๋ฆฌํ๊ฑฐ๋
- ์คํ์ ์ธ use๋ฅผ ํ์ฉํ๋ฉด ๋์ฑ ๊น๋ํ ๊ตฌ์กฐ๋ฅผ ๋ง๋ค ์ ์๋ค
react19์ ์ถ๊ฐ๋ useํ
์ผ๋ก ๋น๋๊ธฐ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃจ๋ ๋ฐฉ์ ๋ํ ํจ์ฌ ์์ฐ์ค๋ฝ๊ณ ์ง๊ด์ ์ผ๋ก ์งํํ๊ณ ์๋ค.
์ด๋ฅผ ์ ํ์ฉํ๋ฉด ์ฌ์ฉ์ ๊ฒฝํ๊ณผ ๊ฐ๋ฐ ํจ์จ์ฑ ๋ชจ๋๋ฅผ ํฅ์์ํฌ ์ ์๋ค.
ย
์์
์ด๊ณณ์์ ์์ ๋ฅผ ํ์ธํด๋ณด์ค ์ ์์ต๋๋ค.
- client-component
- async-component
- use-component
์์ผ๋ก ๋น๋๊ธฐ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ๋ฐฉ์์ ๋ณํ๋ฅผ ํ์ธํด๋ณด์๋๊ฒ์ ์ถ์ฒ๋๋ฆฝ๋๋ค.
ย
react-use
entrolEC โข Updated Jun 29, 2025
ย
ย