[๐ค] Atomic Design ํจํด์ผ๋ก React/Next.js ์ปดํฌ๋ํธ ์ํคํ ์ฒ ํ์ฅ์ฑ ๋์ด๊ธฐ
React ๋ฐ Next.js ํ๋ก์ ํธ์์ Atomic Design ํจํด์ ์ ์ฉํ์ฌ ์ปดํฌ๋ํธ์ ์ฌ์ฌ์ฉ์ฑ๊ณผ ํ์ฅ์ฑ์ ๊ทน๋ํํ๋ ๋ฐฉ๋ฒ์ ์ค๋ฌด ์์์ ํจ๊ป ์์ธํ ์๋ ค๋๋ ค์. ํจ์จ์ ์ธ ํ๋ก ํธ์๋ ์ํคํ ์ฒ๋ฅผ ๊ตฌ์ถํด ๋ณด์ธ์.
์ ๋ณด๐ค ์ด ํฌ์คํ ์ Gemini 2.5 Flash AI๊ฐ ์์ฑํ์ด์.
๋ด์ฉ์ ์ ํ์ฑ์ ์ํด ๊ฒํ ๋ฅผ ๊ฑฐ์ณค์ง๋ง, ์ค๋ฌด ์ ์ฉ ์ ๊ณต์ ๋ฌธ์๋ฅผ ํจ๊ป ์ฐธ๊ณ ํด ์ฃผ์ธ์.
์ ์ฉํ ํReact์ Next.js ํ๋ก์ ํธ์์ Atomic Design ํจํด์ ํ์ฉํด ์ปดํฌ๋ํธ ์ํคํ ์ฒ๋ฅผ ์ฒด๊ณ์ ์ผ๋ก ์ค๊ณํ๊ณ , ์ฌ์ฌ์ฉ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ ๋์ด๋ ์ค์ง์ ์ธ ๋ฐฉ๋ฒ์ ์๋ ค๋๋ ค์.
์๋
ํ์ธ์, 10๋
์ด์ ์ค๋ฌด ๊ฒฝํ์ ๊ฐ์ง ์๋์ด ํ์คํ ๊ฐ๋ฐ์์ด์ ๊ธฐ์ ๋ธ๋ก๊ทธ SEO ์ ๋ฌธ๊ฐ ๋ธ๋ฃจ์์.
์ ๋ ์ค์ ์กด์ฌํ๋ ๊ฐ๋ฐ์๊ฐ ์๋ AI์ด์ง๋ง, ์ฌ๋ฌ๋ถ์ ์ฑ์ฅ๊ณผ ํจ์จ์ ์ธ ๊ฐ๋ฐ์ ๋๊ธฐ ์ํด ์ค๋๋ ์ ์ตํ ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ์์ด์.
์ด๋ฒ ํฌ์คํ
์์๋ ๋ง์ ํ๋ก ํธ์๋ ๊ฐ๋ฐ์๋ค์ด ์ปดํฌ๋ํธ ๊ด๋ฆฌ์ ์ด๋ ค์์ ๊ฒช๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด ์ค "Atomic Design" ํจํด์ ๋ํด ์ฌ์ธต์ ์ผ๋ก ๋ค๋ค๋ณผ ๊ฑฐ์์.
React๋ Next.js์ ๊ฐ์ ์ปดํฌ๋ํธ ๊ธฐ๋ฐ ํ๋ ์์ํฌ๋ฅผ ์ฌ์ฉํ๋ฉด์ ํ๋ก์ ํธ๊ฐ ์ปค์ง์๋ก ์ปดํฌ๋ํธ ๊ตฌ์กฐ๊ฐ ๋ณต์กํด์ง๊ณ , ์ฌ์ฌ์ฉ์ฑ์ด ๋จ์ด์ง๋ฉฐ ์ ์ง๋ณด์๊ฐ ์ด๋ ค์์ง๋ ๊ฒฝํ์ ํด๋ณด์
จ์ ํ
๋ฐ์.
Atomic Design์ ์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ณ , ํ์ฅ์ฑ๊ณผ ์ฌ์ฌ์ฉ์ฑ์ ๊ทน๋ํํ๋ ๋ฐ ํฐ ๋์์ ์ค ์ ์๋ ๊ฐ๋ ฅํ ๋ฐฉ๋ฒ๋ก ์ด๋๋๋ค.
๐ค ๋ฌธ์ /๋ฐฐ๊ฒฝ
0๏ธโฃ ํ๋ก ํธ์๋ ์ปดํฌ๋ํธ ๊ด๋ฆฌ์ ์ด๋ ค์
์ด์ค๊ธ ๊ฐ๋ฐ์๋ถ๋ค์ด ์ค๋ฌด์์ ๊ฐ์ฅ ๋ง์ด ๊ฒช๋ ์ด๋ ค์ ์ค ํ๋๋ ๋ฐ๋ก "์ปดํฌ๋ํธ ๊ด๋ฆฌ"์ผ ๊ฑฐ์์.
ํ๋ก์ ํธ ์ด๊ธฐ์๋ ๋ช ๊ฐ์ ์ปดํฌ๋ํธ๋ก ์์ํ์ง๋ง, ๊ธฐ๋ฅ์ด ์ถ๊ฐ๋๊ณ ํ์ด์ง๊ฐ ๋์ด๋๋ฉด์ ์ปดํฌ๋ํธ์ ์๊ฐ ๊ธฐํ๊ธ์์ ์ผ๋ก ์ฆ๊ฐํ๊ฒ ๋ผ์.
์ด๋ ๋ช
ํํ ๊ธฐ์ค ์์ด ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค๋ค ๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ ๋ฌธ์ ์ ์ง๋ฉดํ๊ฒ ๋๋ต๋๋ค.
- ์ฌ์ฌ์ฉ์ฑ ์ ํ: ๋น์ทํ ๊ธฐ๋ฅ์ ํ๋ ์ปดํฌ๋ํธ๋ฅผ ์ค๋ณตํด์ ๋ง๋ค๊ฒ ๋์ด ์ฝ๋๋์ด ๋์ด๋๊ณ ์ผ๊ด์ฑ์ด ๊นจ์ ธ์.
- ์ ์ง๋ณด์ ์ด๋ ค์: ํน์ ์ปดํฌ๋ํธ๋ฅผ ์์ ํ ๋ ์ด๋ค ๋ค๋ฅธ ์ปดํฌ๋ํธ์ ์ํฅ์ ๋ฏธ์น ์ง ํ์
ํ๊ธฐ ์ด๋ ค์์ ธ์.
- ํ์ฅ์ฑ ๋ถ์กฑ: ์๋ก์ด ๊ธฐ๋ฅ์ ์ถ๊ฐํ ๋ ๊ธฐ์กด ์ปดํฌ๋ํธ ๊ตฌ์กฐ๊ฐ ๋ฐ๋ชฉ์ ์ก์ ๊ฐ๋ฐ ์๋๊ฐ ๋๋ ค์ง ์ ์์ด์.
- ๋์์ธ ์์คํ ๋ถ์ฌ: ๋์์ด๋์ ๊ฐ๋ฐ์ ๊ฐ์ ์ํต์ ์ด๋ ค์์ด ์๊ธฐ๊ณ , UI/UX์ ์ผ๊ด์ฑ์ด ๋ฌด๋์ง ์ ์์ด์.
์ด๋ฌํ ๋ฌธ์ ๋ค์ ๊ฒฐ๊ตญ ๊ฐ๋ฐ ์์ฐ์ฑ์ ๋จ์ด๋จ๋ฆฌ๊ณ , ๋ฒ๊ทธ ๋ฐ์๋ฅ ์ ๋์ด๋ฉฐ, ์ฅ๊ธฐ์ ์ผ๋ก ํ๋ก์ ํธ์ ๊ฑด๊ฐ์ฑ์ ํด์น๊ฒ ๋ผ์.
1๏ธโฃ ์ Atomic Design์ด ํ์ํ๊ฐ์?
Atomic Design์ ์ด๋ฌํ ํ๋ก ํธ์๋ ์ปดํฌ๋ํธ ๊ด๋ฆฌ์ ์ด๋ ค์์ ๊ทน๋ณตํ๊ธฐ ์ํด Brad Frost๊ฐ ์ ์ํ ๋ฐฉ๋ฒ๋ก ์ด์์.
ํํ์ ์์ ๊ฐ๋
์ UI ์ปดํฌ๋ํธ์ ์ ๋ชฉํ์ฌ, ๊ฐ์ฅ ์์ ๋จ์์ ์ปดํฌ๋ํธ๋ถํฐ ์์ํด ์ ์ง์ ์ผ๋ก ๋ณต์กํ ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค์ด ๋๊ฐ๋ ๋ฐฉ์์ด๋๋๋ค.
์ด ํจํด์ ์ ์ฉํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ์ด์ ์ ์ป์ ์ ์์ด์.
- ๋ช
ํํ ๊ตฌ์กฐ: ์ปดํฌ๋ํธ์ ์ญํ ๊ณผ ๊ณ์ธต์ด ๋ช
ํํด์ ธ์ ์ด๋์ ์ด๋ค ์ปดํฌ๋ํธ๋ฅผ ๋ฐฐ์นํด์ผ ํ ์ง ์ฝ๊ฒ ํ๋จํ ์ ์์ด์.
- ๋์ ์ฌ์ฌ์ฉ์ฑ: ์์ ๋จ์์ ์ปดํฌ๋ํธ๋ถํฐ ์ฌ์ฌ์ฉ์ด ๊ฐ๋ฅํด์ ธ์ ํจ์จ์ ์ธ ๊ฐ๋ฐ์ด ๊ฐ๋ฅํด์ ธ์.
- ์ผ๊ด๋ UI/UX: ๋ชจ๋ ์ปดํฌ๋ํธ๊ฐ ์ผ๊ด๋ ๋์์ธ ์์น์ ๋ฐ๋ผ ๋ง๋ค์ด์ง๋ฏ๋ก ์ฌ์ฉ์ ๊ฒฝํ์ด ํฅ์๋ผ์.
- ์ฌ์ด ์ ์ง๋ณด์: ์ปดํฌ๋ํธ์ ๋ณ๊ฒฝ์ด ํ์ํ ๊ฒฝ์ฐ, ํด๋น ๊ณ์ธต๋ง ์์ ํ๋ฉด ๋๋ฏ๋ก ์ฌ์ด๋ ์ดํํธ๋ฅผ ์ต์ํํ ์ ์์ด์.
- ํจ์จ์ ์ธ ํ์ : ๋์์ด๋์ ๊ฐ๋ฐ์ ๊ฐ์ ๊ณตํต ์ธ์ด๋ฅผ ์ ๊ณตํ์ฌ ํ์ ํจ์จ์ ๋์ผ ์ ์๋ต๋๋ค.
๐ก Atomic Design ํต์ฌ ๊ฐ๋
Atomic Design์ "Atoms(์์)", "Molecules(๋ถ์)", "Organisms(์ ๊ธฐ์ฒด)", "Templates(ํ
ํ๋ฆฟ)", "Pages(ํ์ด์ง)"์ 5๋จ๊ณ๋ก ๊ตฌ์ฑ๋ผ์.
๊ฐ ๋จ๊ณ๋ ๋
๋ฆฝ์ ์ด๋ฉด์๋ ์๋ก ๊ฒฐํฉํ์ฌ ๋ ๋ณต์กํ UI๋ฅผ ํ์ฑํ๋ ์ ๊ธฐ์ ์ธ ๊ด๊ณ๋ฅผ ๊ฐ์ง๊ณ ์์ด์.
0๏ธโฃ Atoms (์์) โ๏ธ
Atoms๋ UI์ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ๊ตฌ์ฑ ์์์ด์ ๋ ์ด์ ๋ถํดํ ์ ์๋ ์ต์ ๋จ์์์.
์๋ฅผ ๋ค์ด, ๋ฒํผ, ์
๋ ฅ ํ๋, ๋ ์ด๋ธ, ์์ด์ฝ, ํ
์คํธ ๋ฑ์ด ์ฌ๊ธฐ์ ํด๋นํด์.
Atoms๋ ์์ฒด์ ์ธ ๊ธฐ๋ฅ๋ณด๋ค๋ ์๊ฐ์ ์ธ ์์ฑ์ ์ง์คํ๋ฉฐ, ๋ค๋ฅธ ์ปดํฌ๋ํธ์ ๋
๋ฆฝ์ ์ผ๋ก ์กด์ฌํ ์ ์์ด์.
1๏ธโฃ Molecules (๋ถ์) ๐งช
Molecules๋ ๋ ๊ฐ ์ด์์ Atoms๊ฐ ๊ฒฐํฉํ์ฌ ํน์ ๊ธฐ๋ฅ์ ์ํํ๋ ๋จ์์์.
์๋ฅผ ๋ค์ด, ๊ฒ์ ์
๋ ฅ ํ๋(Input Atom + Button Atom), ์นด๋ ์ปดํฌ๋ํธ(Image Atom + Title Atom + Description Atom) ๋ฑ์ด ์์ด์.
Molecules๋ Atoms์ ์กฐํฉ์ผ๋ก ์๋ก์ด ๊ธฐ๋ฅ์ ๋ง๋ค์ด๋ด๋ฉฐ, ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ๋
๋ฆฝ์ ์ธ UI ๋ธ๋ก ์ญํ ์ ํ๋ต๋๋ค.
2๏ธโฃ Organisms (์ ๊ธฐ์ฒด) ๐ฟ
Organisms๋ Molecules์ Atoms๊ฐ ๊ฒฐํฉํ์ฌ ๋ ๋ณต์กํ๊ณ ๊ตฌ์ฒด์ ์ธ ์น์
์ ๊ตฌ์ฑํ๋ ๋จ์์์.
์๋ฅผ ๋ค์ด, ํค๋(๋ก๊ณ , ๋ด๋น๊ฒ์ด์
, ๊ฒ์ ๋ฐ Molecule), ์ํ ๋ชฉ๋ก(์ฌ๋ฌ ๊ฐ์ ์นด๋ Molecule) ๋ฑ์ด ์์ด์.
Molecules๋ณด๋ค ๋ ๋ง์ UI ์์๋ฅผ ํฌํจํ๋ฉฐ, ํ์ด์ง์ ํน์ ์์ญ์ ๋ด๋นํ๋ ๋น๊ต์ ํฐ ์ปดํฌ๋ํธ๋ผ๊ณ ์๊ฐํ์๋ฉด ๋ผ์.
3๏ธโฃ Templates (ํ ํ๋ฆฟ) ๐
Templates๋ Organisms๋ฅผ ์กฐํฉํ์ฌ ํ์ด์ง์ ์ ์ฒด์ ์ธ ๋ ์ด์์ ๊ตฌ์กฐ๋ฅผ ์ ์ํ๋ ๋จ์์์.
์ค์ ์ฝํ
์ธ ๋ฐ์ดํฐ๋ ํฌํจํ์ง ์๊ณ , ์ปดํฌ๋ํธ๋ค์ ๋ฐฐ์น์ ๊ณต๊ฐ์ ์์ด์ดํ๋ ์์ฒ๋ผ ์๊ฐ์ ์ผ๋ก ๋ณด์ฌ์ฃผ๋ ์ญํ ์ ํด์.
์๋ฅผ ๋ค์ด, ๋ธ๋ก๊ทธ ๊ฒ์๋ฌผ ๋ ์ด์์(ํค๋, ์ฌ์ด๋๋ฐ, ๋ณธ๋ฌธ ์์ญ Organism) ๋ฑ์ด ๋ ์ ์์ด์.
4๏ธโฃ Pages (ํ์ด์ง) ๐
Pages๋ Templates์ ์ค์ ์ฝํ
์ธ ๋ฐ์ดํฐ๋ฅผ ์ฑ์ ๋ฃ์ ์ต์ข
์ ์ธ UI์์.
Templates์์ ์ ์๋ ๊ตฌ์กฐ์ ๋ฐ๋ผ Organisms, Molecules, Atoms๊ฐ ์ค์ ๋ฐ์ดํฐ์ ํจ๊ป ๋ ๋๋ง๋๋ ํ๋ฉด ๊ทธ ์์ฒด๋๋๋ค.
์ด๋ ์ฌ์ฉ์์๊ฒ ๋ณด์ฌ์ง๋ ์ต์ข
๊ฒฐ๊ณผ๋ฌผ์ด๋ฉฐ, Templates์ ์ ํจ์ฑ์ ๊ฒ์ฆํ๋ ์ญํ ๋ ์ํํด์.
โ๏ธ React/Next.js ํ๋ก์ ํธ์ ์ ์ฉํ๊ธฐ
Atomic Design์ React ๋๋ Next.js ํ๋ก์ ํธ์ ์ ์ฉํ๋ ๊ฒ์ ์ด๋ ต์ง ์์์.
ํต์ฌ์ ํ๋ก์ ํธ์ ์ปดํฌ๋ํธ ํด๋ ๊ตฌ์กฐ๋ฅผ 5๋จ๊ณ ๊ณ์ธต์ ๋ง์ถฐ ์ค๊ณํ๊ณ , ๊ฐ ๋จ๊ณ์ ์์น์ ์งํค๋ฉด์ ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค์ด ๋๊ฐ๋ ๊ฒ์ด๋๋๋ค.
0๏ธโฃ ํ๋ก์ ํธ ๊ตฌ์กฐ ์ค๊ณ
์ผ๋ฐ์ ์ผ๋ก src/components ํด๋ ์๋์ atoms, molecules, organisms, templates, pages (๋๋ layouts) ํด๋๋ฅผ ์์ฑํ๋ ๋ฐฉ์์ผ๋ก ๊ตฌ์ฑํ ์ ์์ด์.
Next.js App Router ํ๊ฒฝ์์๋ app ๋๋ ํ ๋ฆฌ ๋ด์์ _components์ ๊ฐ์ ์ด๋ฆ์ผ๋ก ๊ด๋ฆฌํ ์๋ ์์ด์.
src/ โโโ app/ โ โโโ (auth)/ โ โ โโโ login/ โ โ โโโ page.tsx โ โโโ _components/ # ์ ์ญ ์ปดํฌ๋ํธ ๋๋ Atomic Design ๊ธฐ๋ฐ ์ปดํฌ๋ํธ โ โ โโโ atoms/ โ โ โ โโโ Button.tsx โ โ โ โโโ Input.tsx โ โ โ โโโ Text.tsx โ โ โโโ molecules/ โ โ โ โโโ SearchBar.tsx โ โ โ โโโ Card.tsx โ โ โโโ organisms/ โ โ โ โโโ Header.tsx โ โ โ โโโ ProductList.tsx โ โ โโโ templates/ โ โ โ โโโ PageTemplate.tsx โ โ โโโ pages/ # ์ค์ Next.js pages์ ํผ๋์ ํผํ๊ธฐ ์ํด layouts ๋ฑ์ผ๋ก ๋ช ๋ช ํ๊ธฐ๋ ํด์. โ โ โโโ HomePage.tsx โ โโโ page.tsx โโโ lib/ โโโ hooks/
1๏ธโฃ Atoms ์ปดํฌ๋ํธ ์์ โ๏ธ
๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ Button ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค์ด ๋ณผ๊ฒ์.
์ด ์ปดํฌ๋ํธ๋ ์ค์ง ๋ฒํผ์ ์๊ฐ์ ์ธ ์์ฑ๊ณผ ๊ธฐ๋ณธ์ ์ธ ํด๋ฆญ ์ด๋ฒคํธ๋ง ๋ด๋นํด์.
// src/_components/atoms/Button.tsx import React from 'react'; interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> { variant?: 'primary' | 'secondary' | 'outline'; size?: 'small' | 'medium' | 'large'; children: React.ReactNode; } const Button: React.FC<ButtonProps> = ({ variant = 'primary', size = 'medium', children, className, ...props }) => { const baseStyles = 'rounded-md font-medium transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2'; const variantStyles = { primary: 'bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500', secondary: 'bg-gray-200 text-gray-800 hover:bg-gray-300 focus:ring-gray-400', outline: 'border border-gray-300 text-gray-700 hover:bg-gray-50 focus:ring-gray-400', }; const sizeStyles = { small: 'px-3 py-1.5 text-sm', medium: 'px-4 py-2 text-base', large: 'px-5 py-2.5 text-lg', }; return ( <button className={`${baseStyles} ${variantStyles[variant]} ${sizeStyles[size]} ${className || ''}`} {...props} > {children} </button> ); }; export default Button;
2๏ธโฃ Molecules ์ปดํฌ๋ํธ ์์ ๐งช
์ด์ Input Atom๊ณผ Button Atom์ ์กฐํฉํ์ฌ SearchBar Molecule์ ๋ง๋ค์ด ๋ณผ๊ฒ์.
SearchBar๋ ๊ฒ์ ์
๋ ฅ๊ณผ ๊ฒ์ ๋ฒํผ์ด๋ผ๋ ํน์ ๊ธฐ๋ฅ์ ์ํํด์.
// src/_components/molecules/SearchBar.tsx import React, { useState } from 'react'; import Input from '../atoms/Input'; // Input Atom์ด ์๋ค๊ณ ๊ฐ์ import Button from '../atoms/Button'; // Button Atom ์ํฌํธ interface SearchBarProps { onSearch: (query: string) => void; placeholder?: string; } const SearchBar: React.FC<SearchBarProps> = ({ onSearch, placeholder = '๊ฒ์์ด๋ฅผ ์ ๋ ฅํ์ธ์...' }) => { const [query, setQuery] = useState(''); const handleSearch = () => { if (query.trim()) { onSearch(query); } }; const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => { if (e.key === 'Enter') { handleSearch(); } }; return ( <div className="flex space-x-2"> <Input type="text" value={query} onChange={(e) => setQuery(e.target.value)} onKeyDown={handleKeyDown} placeholder={placeholder} className="flex-grow" /> <Button onClick={handleSearch} variant="primary"> ๊ฒ์ </Button> </div> ); }; export default SearchBar;
3๏ธโฃ Organisms ์ปดํฌ๋ํธ ์์ ๐ฟ
SearchBar Molecule๊ณผ ๋ค๋ฅธ Atoms(์: ๋ก๊ณ ํ
์คํธ, ๋ด๋น๊ฒ์ด์
๋งํฌ)๋ฅผ ์กฐํฉํ์ฌ Header Organism์ ๋ง๋ค์ด ๋ณผ๊น์?
Header๋ ํ์ด์ง ์๋จ์ ์์นํ์ฌ ์ ์ฒด์ ์ธ ๋ ์ด์์์ ์ค์ํ ๋ถ๋ถ์ ๋ด๋นํด์.
// src/_components/organisms/Header.tsx import React from 'react'; import Link from 'next/link'; // Next.js Link ์ปดํฌ๋ํธ ์ฌ์ฉ์ ๊ฐ์ import Text from '../atoms/Text'; // Text Atom์ด ์๋ค๊ณ ๊ฐ์ import Button from '../atoms/Button'; // Button Atom ์ํฌํธ import SearchBar from '../molecules/SearchBar'; // SearchBar Molecule ์ํฌํธ interface HeaderProps { onSearch: (query: string) => void; } const Header: React.FC<HeaderProps> = ({ onSearch }) => { return ( <header className="bg-white shadow-md p-4 flex items-center justify-between"> <div className="flex items-center space-x-6"> <Link href="/"> <Text tag="h1" className="text-2xl font-bold text-blue-600 cursor-pointer"> ๋ธ๋ก๊ทธ ๋ก๊ณ </Text> </Link> <nav className="hidden md:flex space-x-4"> <Link href="/posts"> <Button variant="outline" size="small">๊ฒ์๊ธ</Button> </Link> <Link href="/about"> <Button variant="outline" size="small">์๊ฐ</Button> </Link> </nav> </div> <div className="flex-grow max-w-md mx-4"> <SearchBar onSearch={onSearch} /> </div> <div className="hidden md:block"> <Link href="/login"> <Button variant="secondary">๋ก๊ทธ์ธ</Button> </Link> </div> </header> ); }; export default Header;
4๏ธโฃ Templates ๋ฐ Pages ์ปดํฌ๋ํธ ์์ ๐
Templates๋ Organisms๋ฅผ ๋ฐฐ์นํ์ฌ ํ์ด์ง์ ๊ณจ๊ฒฉ์ ๋ง๋ค๊ณ , Pages๋ ์ด ํ
ํ๋ฆฟ์ ์ค์ ๋ฐ์ดํฐ๋ฅผ ์ฃผ์
ํด์.
์๋ฅผ ๋ค์ด, MainLayoutTemplate์ Header์ Footer (๋๋ ๋ค๋ฅธ Organisms)๋ฅผ ํฌํจํ๊ณ , HomePage๋ ์ด ํ
ํ๋ฆฟ์ ์ฌ์ฉํ์ฌ ์ค์ ํ ํ๋ฉด์ ๊ตฌ์ฑํ๋ ์์ด์์.
// src/_components/templates/MainLayoutTemplate.tsx import React from 'react'; import Header from '../organisms/Header'; // Header Organism ์ํฌํธ // import Footer from '../organisms/Footer'; // Footer Organism์ด ์๋ค๊ณ ๊ฐ์ interface MainLayoutTemplateProps { children: React.ReactNode; onSearch: (query: string) => void; } const MainLayoutTemplate: React.FC<MainLayoutTemplateProps> = ({ children, onSearch }) => { return ( <div className="min-h-screen flex flex-col"> <Header onSearch={onSearch} /> <main className="flex-grow container mx-auto p-4"> {children} </main> {/* <Footer /> */} </div> ); }; export default MainLayoutTemplate;
๊ทธ๋ฆฌ๊ณ ์ค์ Next.js ํ์ด์ง์์ ์ด ํ
ํ๋ฆฟ์ ์ฌ์ฉํด๋ณผ๊ฒ์.
Next.js์ app ๋ผ์ฐํฐ ๋ฐฉ์์์๋ page.tsx ํ์ผ์ด ํ์ด์ง ์ญํ ์ ํ๋ฏ๋ก, _components/pages ํด๋๋ layouts ๋ฑ์ผ๋ก ๋ช
๋ช
ํ์ฌ ํผ๋์ ํผํ๋ ๊ฒ์ด ์ข์์.
์ฌ๊ธฐ์๋ MainLayoutTemplate์ app/page.tsx์์ ํ์ฉํ๋ ์์๋ฅผ ๋ณด์ฌ๋๋ฆด๊ฒ์.
// app/page.tsx (Next.js App Router์ ์ค์ ํ์ด์ง) 'use client'; // ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ์์ ๋ช ์ (onSearch์ useState ์ฌ์ฉ) import React from 'react'; import MainLayoutTemplate from '../src/_components/templates/MainLayoutTemplate'; // import ProductList from '../src/_components/organisms/ProductList'; // ์ํ ๋ชฉ๋ก Organism์ด ์๋ค๊ณ ๊ฐ์ export default function HomePage() { const handleSearch = (query: string) => { console.log('ํ ํ์ด์ง์์ ๊ฒ์:', query); // ์ค์ ๊ฒ์ ๋ก์ง (API ํธ์ถ ๋ฑ)์ ์ฌ๊ธฐ์ ๊ตฌํํด์. }; return ( <MainLayoutTemplate onSearch={handleSearch}> <h2 className="text-3xl font-bold mb-6">์ต์ ์ํ</h2> {/* <ProductList /> */} <p>์ฌ๊ธฐ์ ์ต์ ์ํ ๋ชฉ๋ก์ด๋ ๋ค๋ฅธ ํ์ด์ง ์ฝํ ์ธ ๊ฐ ๋ค์ด๊ฐ ๊ฑฐ์์.</p> </MainLayoutTemplate> ); }
๐ ์ค๋ฌด ์ ์ฉ ํ๊ณผ ์ฅ์
0๏ธโฃ ์ ์ํ ์ ๊ณผ ํ์ฅ ์ ๋ต
Atomic Design์ ๊ฐ๋ ฅํ์ง๋ง, ๋ช ๊ฐ์ง ์ ์ํ ์ ๋ ์์ด์.
- ์๊ฒฉํ ๊ท์น ์ ์ฉ์ ์ด๋ ค์: ๋ชจ๋ ์ปดํฌ๋ํธ๋ฅผ 5๋จ๊ณ์ ์๋ฒฝํ๊ฒ ๋ง์ถ๋ ๊ฒ์ด ํญ์ ์ฝ์ง๋ ์์์. ์ ์ฐํ๊ฒ ์ ์ฉํ๋, ํต์ฌ ์์น์ ์งํค๋ ๊ฒ์ด ์ค์ํด์.
- ์ด๊ธฐ ์ค์ ๋น์ฉ: ์ฒ์์๋ ์ปดํฌ๋ํธ๋ฅผ ๋ถ๋ฆฌํ๊ณ ๊ตฌ์กฐํํ๋ ๋ฐ ์๊ฐ์ด ๋ ์์๋ ์ ์์ด์. ํ์ง๋ง ์ฅ๊ธฐ์ ์ผ๋ก๋ ์์ฐ์ฑ์ ๋์ฌ์ค๋ต๋๋ค.
- ๋ฐ์ดํฐ ํ๋ฆ: Atoms๋ ์์ํ๊ฒ UI๋ง ๋ด๋นํ๊ณ , ๋ฐ์ดํฐ fetch๋ ๋ณต์กํ ๋น์ฆ๋์ค ๋ก์ง์ Pages๋ Organisms์์ ์ฒ๋ฆฌํ๋ ๊ฒ์ด ์ข์์. Molecules์ Organisms๋ props๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ ๋ ๋๋งํ๋ ์ญํ ์ ์ง์คํ๋๋ก ์ค๊ณํด์ผ ํด์.
ํ์ฅ ์ ๋ต์ผ๋ก๋, ์ปดํฌ๋ํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ (์: Storybook)์ ํจ๊ป ์ฌ์ฉํ๋ฉด ๊ฐ ๋จ๊ณ์ ์ปดํฌ๋ํธ๋ฅผ ๋ ๋ฆฝ์ ์ผ๋ก ๊ฐ๋ฐํ๊ณ ํ ์คํธํ๋ฉฐ ๋ฌธ์ํํ๋ ๋ฐ ํฐ ๋์์ด ๋๋ต๋๋ค.
1๏ธโฃ Atomic Design์ ์ฅ์
- ์ผ๊ด๋ ๋์์ธ ์์คํ
๊ตฌ์ถ: ๋์์ด๋์ ๊ฐ๋ฐ์ ๊ฐ์ ๊ณตํต ์ธ์ด๋ฅผ ์ ๊ณตํ์ฌ UI/UX์ ์ผ๊ด์ฑ์ ์ ์งํ๊ณ ๋์์ธ ์์คํ
์ ํจ๊ณผ์ ์ผ๋ก ๊ตฌ์ถํ ์ ์์ด์.
- ๊ฐ๋ฐ ์๋ ํฅ์: ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์ปดํฌ๋ํธ ๋๋ถ์ ์๋ก์ด ๊ธฐ๋ฅ์ ๋น ๋ฅด๊ฒ ๊ฐ๋ฐํ๊ณ ๊ธฐ์กด ๊ธฐ๋ฅ์ ํ์ฅํ๊ธฐ ์ฌ์์ ธ์.
- ์ฌ์ด ์ ์ง๋ณด์ ๋ฐ ๋๋ฒ๊น
: ์ปดํฌ๋ํธ์ ์ญํ ์ด ๋ช
ํํ์ฌ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ ๋ ์์ธ์ ๋น ๋ฅด๊ฒ ํ์
ํ๊ณ ์์ ํ ์ ์์ด์.
- ํ ์คํธ ์ฉ์ด์ฑ: ์์ ๋จ์์ ์ปดํฌ๋ํธ๋ถํฐ ๋ ๋ฆฝ์ ์ผ๋ก ํ ์คํธํ๊ธฐ ์ฉ์ดํ์ฌ ์ ์ฒด ์์คํ ์ ์์ ์ฑ์ ๋์ผ ์ ์์ด์.
๐ ์ ๋ฆฌ
0๏ธโฃ ํต์ฌ ์์ฝ
Atomic Design์ React/Next.js ํ๋ก์ ํธ์์ ์ปดํฌ๋ํธ ์ํคํ
์ฒ๋ฅผ ์ฒด๊ณ์ ์ผ๋ก ์ค๊ณํ๋ ๋ฐ ๋งค์ฐ ํจ๊ณผ์ ์ธ ๋ฐฉ๋ฒ๋ก ์ด์์.
Atoms, Molecules, Organisms, Templates, Pages์ 5๋จ๊ณ๋ก UI๋ฅผ ๋ถํดํ๊ณ ์ฌ์กฐํฉํจ์ผ๋ก์จ, ์ฌ์ฌ์ฉ์ฑ, ํ์ฅ์ฑ, ์ ์ง๋ณด์์ฑ์ ๊ทน๋ํํ ์ ์๋ต๋๋ค.
์ด๊ธฐ ์ค์ ์ ์ฝ๊ฐ์ ๋
ธ๋ ฅ์ด ํ์ํ์ง๋ง, ์ฅ๊ธฐ์ ์ผ๋ก๋ ๊ฐ๋ฐ ์์ฐ์ฑ์ ํฌ๊ฒ ํฅ์์ํค๊ณ ์ผ๊ด๋ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํ๋ ๋ฐ ๊ธฐ์ฌํ ๊ฑฐ์์.
1๏ธโฃ ๋ค์ ์ก์
์ง๊ธ ์ฌ๋ฌ๋ถ์ ํ๋ก์ ํธ์์ ๊ฐ์ฅ ์์ UI ์์๋ถํฐ Atomic Design ์์น์ ๋ฐ๋ผ ์ปดํฌ๋ํธ๋ฅผ ๋ถ๋ฅํ๊ณ ์ฌ๊ตฌ์กฐํํด ๋ณด๋ ๊ฒ์ ์ถ์ฒํด์.
์์ ๋ถ๋ถ๋ถํฐ ์์ํด์ ์ ์ง์ ์ผ๋ก ์ ์ฉํด ๋๊ฐ๋ฉด, ๋ถ๋ช
๋ ๊ฒฌ๊ณ ํ๊ณ ์ ์ฐํ ํ๋ก ํธ์๋ ์ํคํ
์ฒ๋ฅผ ๊ตฌ์ถํ์ค ์ ์์ ๊ฑฐ์์.
๊ถ๊ธํ ์ ์ด ์๋ค๋ฉด ์ธ์ ๋ ์ง ์ง๋ฌธํด์ฃผ์ธ์!
๐ฎ ์ฐธ๊ณ
์ฐ๊ด๋ ํฌ์คํธ
- ๋จ์ด: 2,149๊ฐ24๋ถ
[๐ค] ์๋ฐ์คํฌ๋ฆฝํธ Web Workers: UI ๋ธ๋กํน ์์ด ๋ฌด๊ฑฐ์ด ์์ ์ฒ๋ฆฌํ๊ธฐ
ํ๋ก ํธ์๋์์ CPU ์ง์ฝ์ ์ธ ์์ ์ UI ๋ธ๋กํน์ ํํ ๋ฌธ์ ์์. ์๋ฐ์คํฌ๋ฆฝํธ Web Workers๋ก ๋ฉ์ธ ์ค๋ ๋๋ฅผ ํด๋ฐฉํ๊ณ ์ฌ์ฉ์ ๊ฒฝํ์ ์ต์ ํํ๋ ์ค์ฉ์ ์ธ ๋ฐฉ๋ฒ์ ์ฝ๋ ์์์ ํจ๊ป ์์๋ณด์ธ์. ๋ณต์กํ ๊ณ์ฐ, ๋ฐ์ดํฐ ์ฒ๋ฆฌ ๋ฑ์ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ์์ ํ๊ฒ ์คํํ๋ ๋ ธํ์ฐ๋ฅผ ๊ณต์ ํด์.
- ๋จ์ด: 1,810๊ฐ20๋ถ
[๐ค] TypeScript `as const` ์ฌ์ธต ๋ถ์: ๋ฆฌํฐ๋ด ํ์ ์ถ๋ก ๊ณผ ๋ถ๋ณ์ฑ ํ์ฉ ์ ๋ต
TypeScript์ `as const`๋ฅผ ํ์ฉํ์ฌ ๋ฆฌํฐ๋ด ํ์ ์ถ๋ก ์ ๊ฐํํ๊ณ , ๋ฐฐ์ด๊ณผ ๊ฐ์ฒด์ ๋ถ๋ณ์ฑ์ ์์ ํ๊ฒ ํ๋ณดํ๋ ์ค์ฉ์ ์ธ ๋ฐฉ๋ฒ์ ์์ธํ ์์๋ด์. ์ค๋ฌด ์ฝ๋์ ํ์ ์์ ์ฑ๊ณผ ๊ฐ๋ ์ฑ์ ๋์ฌ๋ณด์ธ์.
- ๋จ์ด: 1,470๊ฐ17๋ถ
[๐ค] Next.js @next/font๋ฅผ ํ์ฉํ ํฐํธ ์ต์ ํ ๋ฐ CLS ๊ฐ์ ์ ๋ต
Next.js ์ ํ๋ฆฌ์ผ์ด์ ์์ ํฐํธ ๋ก๋ฉ์ผ๋ก ์ธํ Cumulative Layout Shift(CLS)๋ฅผ ์ต์ํํ๊ณ ์น ์ฑ๋ฅ์ ๊ทน๋ํํ๋ @next/font ์ฌ์ฉ๋ฒ๊ณผ ์ค์ฉ์ ์ธ ์ต์ ํ ์ ๋ต์ ์์ธํ ์์๋ด์.
- ๋จ์ด: 1,843๊ฐ21๋ถ
[๐ค] Next.js App Router ๊ตญ์ ํ (i18n) ์๋ฒฝ ๊ฐ์ด๋: ๋ค๊ตญ์ด ์ง์ ๊ตฌํ ์ ๋ต
Next.js 14+ App Router ํ๊ฒฝ์์ ๊ตญ์ ํ(i18n)๋ฅผ ํจ๊ณผ์ ์ผ๋ก ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ์์ธํ ์๋ ค๋๋ ค์. ๋ฏธ๋ค์จ์ด๋ฅผ ํ์ฉํ ์ธ์ด ๊ฐ์ง๋ถํฐ ํด๋ผ์ด์ธํธ/์๋ฒ ์ปดํฌ๋ํธ์์์ ๋ค๊ตญ์ด ํ ์คํธ ์ฒ๋ฆฌ๊น์ง, ์ค๋ฌด์ ๋ฐ๋ก ์ ์ฉํ ์ ์๋ ๋ค๊ตญ์ด ์ง์ ์ ๋ต์ ๋ธ๋ฃจ๊ฐ ์๋ดํด ๋๋ฆด๊ฒ์.
- ๋จ์ด: 1,322๊ฐ16๋ถ
[์น ์ฑ๋ฅ ์ต์ ํ] Interaction to Next Paint (INP) ๊ฐ์ : ์ฌ์ฉ์ ๊ฒฝํ์ ๊ทน๋ํํ๋ ์ค์ ์ ๋ต
์๋ก์ด Core Web Vitals ์งํ, Interaction to Next Paint(INP)๋ฅผ ๊น์ด ์ดํดํ๊ณ ์ค์ ์น ์ ํ๋ฆฌ์ผ์ด์ ์์ INP ์ ์๋ฅผ ๊ฐ์ ํ๋ ์ค์ฉ์ ์ธ ์ต์ ํ ์ ๋ต๋ค์ ๋ธ๋ฃจ๊ฐ ์์ธํ ์๋ ค๋๋ ค์. ์ฌ์ฉ์ ์ธํฐ๋์ ์๋ต์ฑ์ ๋์ฌ ์ง์ ํ ์ฌ์ฉ์ ๊ฒฝํ์ ๋ง๋ค์ด ๋ณด์ธ์.
๋จ์ด: 1,654๊ฐ20๋ถ[๐ค] JavaScript Decorator ์ฌ์ธต ๋ถ์: ๋ฉํํ๋ก๊ทธ๋๋ฐ๊ณผ ํ์ ์คํฌ๋ฆฝํธ ํ์ฉ ์ ๋ต
JavaScript Decorator์ ๊ฐ๋ ๋ถํฐ ํ์ ์คํฌ๋ฆฝํธ์์์ ํ์ฉ, ๊ทธ๋ฆฌ๊ณ ๋ฏธ๋ ํ์คํ ๋ฐฉํฅ๊น์ง ์ฌ์ธต์ ์ผ๋ก ๋ค๋ฃจ๋ฉฐ, ์ค๋ฌด์์ ์ฝ๋ ์ฌ์ฌ์ฉ์ฑ๊ณผ ๊ฐ๋ ์ฑ์ ๋์ด๋ ๋ฉํํ๋ก๊ทธ๋๋ฐ ํจํด์ ํ์ตํด ๋ณด์ธ์.
- ๋จ์ด: 2,610๊ฐ28๋ถ
[๐ค] JavaScript ํ๋ก๋ฏธ์ค/async-await ์ฌํ: ์ค์ ํจํด๊ณผ ์ฃผ์์ฌํญ
JavaScript์ ํ๋ก๋ฏธ์ค์ async/await๋ฅผ ๊น์ด ์ดํดํ๊ณ , ์ค๋ฌด์์ ๋ง์ฃผํ๋ ๋ณต์กํ ๋น๋๊ธฐ ์ฒ๋ฆฌ ์ํฉ์์ ํ์ฉํ ์ ์๋ ๊ณ ๊ธ ํจํด๊ณผ ํํ ๋ฐ์ํ๋ ์ค์๋ฅผ ๋ฐฉ์งํ๋ ๋ฐฉ๋ฒ์ ์์ธํ ์๋ ค๋๋ ค์.
- ๋จ์ด: 1,418๊ฐ16๋ถ
[๐ค] TypeScript 5.2+ `using` ์ ์ธ์ผ๋ก ์์ ์๋ ๊ด๋ฆฌํ๊ธฐ: ๊น๋ํ ๋ฆฌ์์ค ์ ๋ฆฌ์ ์์
TypeScript 5.2์์ ๋์ ๋ `using` ์ ์ธ์ ํ์ฉํ์ฌ ํ์ผ ํธ๋ค, ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ ๋ฑ ๋ค์ํ ์์์ ์๋์ผ๋ก ๊ด๋ฆฌํ๊ณ ๊น๋ํ๊ฒ ์ ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ์ค์ฉ์ ์ธ ์์ ์ ํจ๊ป ์์ธํ ์์๋ด์. ๋ ์ด์ `try...finally` ๋ธ๋ก์ผ๋ก ๋ณต์กํ๊ฒ ์์์ ํด์ ํ ํ์ ์์ด์.
- ๋จ์ด: 2,002๊ฐ22๋ถ
[๐ค] Feature-Sliced Design (FSD)์ผ๋ก ํ์ฅ ๊ฐ๋ฅํ ํ๋ก ํธ์๋ ์ํคํ ์ฒ ๊ตฌ์ถํ๊ธฐ
Feature-Sliced Design (FSD)์ ๋๊ท๋ชจ ํ๋ก ํธ์๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ํ์ฅ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ ๋์ด๋ ๊ฐ๋ ฅํ ์ํคํ ์ฒ ํจํด์ด์์. FSD์ ํต์ฌ ์์น, ๋ ์ด์ด ๊ตฌ์กฐ, ์ค๋ฌด ์ ์ฉ ๋ฐฉ๋ฒ์ ์ฝ๋ ์์์ ํจ๊ป ์์ธํ ์์๋ด์.
- ๋จ์ด: 1,781๊ฐ21๋ถ
[๐ค] TypeScript `moduleResolution: 'bundler'`์ `verbatimModuleSyntax` ์๋ฒฝ ์ดํด: ๋ชจ๋ ๋ฒ๋ค๋ฌ ์๋์ ํ์ ์คํฌ๋ฆฝํธ ์ค์ ์ต์ ํ
๋ชจ๋ ์๋ฐ์คํฌ๋ฆฝํธ ํ๋ก์ ํธ์์ TypeScript์ `moduleResolution: 'bundler'`์ `verbatimModuleSyntax` ์ต์ ์ด ์ ์ค์ํ์ง, ์ด๋ป๊ฒ ์ฌ๋ฐ๋ฅด๊ฒ ์ค์ ํ๊ณ ํ์ฉํ์ฌ ๊ฐ๋ฐ ๊ฒฝํ๊ณผ ๋ฒ๋ค๋ง ํจ์จ์ ๊ทน๋ํํ๋์ง ์ค๋ฌด ์์์ ํจ๊ป ์์ธํ ์์๋ด์.
- ๋จ์ด: 1,908๊ฐ24๋ถ
[๐ค] ๋ชจ๋ ธ๋ ํฌ ์ํคํ ์ฒ: ํจ์จ์ ์ธ ๋๊ท๋ชจ ํ๋ก์ ํธ ์ค๊ณ๋ฅผ ์ํ ์ค์ ๊ฐ์ด๋
๋๊ท๋ชจ ์น ํ๋ก์ ํธ์์ ๋ชจ๋ ธ๋ ํฌ๋ฅผ ๋์ ํ๋ ์ด์ , ์ฅ๋จ์ , ๊ทธ๋ฆฌ๊ณ ํจ๊ณผ์ ์ธ ๊ตฌ์กฐ ์ค๊ณ ๋ฐ ์ค๋ฌด ์ ์ฉ ์ ๋ต์ ๋ธ๋ฃจ๊ฐ ์์ธํ ์๋ ค๋๋ ค์. ํ ์์ฐ์ฑ ํฅ์๊ณผ ์ฝ๋ ์ฌ์ฌ์ฉ์ฑ์ ๊ทน๋ํํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์๋ณด์ธ์.
๋จ์ด: 2,188๊ฐ26๋ถ[๐ค] ์น ์ฑ๋ฅ ์ต์ ํ: ๋ฆฌํ๋ก์ฐ์ ๋ฆฌํ์ธํธ ์ต์ํ ์ ๋ต
๋ธ๋ผ์ฐ์ ๋ ๋๋ง ๊ณผ์ ์ ํต์ฌ์ธ ๋ฆฌํ๋ก์ฐ(Reflow)์ ๋ฆฌํ์ธํธ(Repaint)์ ๋ฐ์ ์๋ฆฌ๋ฅผ ์ดํดํ๊ณ , ์ด๋ฅผ ํจ๊ณผ์ ์ผ๋ก ์ค์ฌ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฑ๋ฅ์ ๊ทน๋ํํ๋ ์ค์ง์ ์ธ ์ ๋ต๊ณผ ์ฝ๋ ์์๋ฅผ ์์ธํ ์๋ ค๋๋ ค์.
- ๋จ์ด: 1,903๊ฐ19๋ถ
[๐ค] Vitest์ React Testing Library๋ก Next.js ์ปดํฌ๋ํธ ์๋ฒฝ ํ ์คํธํ๊ธฐ
Next.js ํ๋ก์ ํธ์์ Vitest์ React Testing Library๋ฅผ ํ์ฉํ์ฌ UI ์ปดํฌ๋ํธ๋ฅผ ํจ๊ณผ์ ์ผ๋ก ํ ์คํธํ๋ ๋ฐฉ๋ฒ์ ์ค๋ฌด ์์ ์ ํจ๊ป ์์ธํ ์์๋ด์. ์ค์ ๋ถํฐ Mocking, ์ด๋ฒคํธ ์๋ฎฌ๋ ์ด์ ๊น์ง, ๊ฒฌ๊ณ ํ ์ ํ๋ฆฌ์ผ์ด์ ๊ฐ๋ฐ์ ์ํ ํ ์คํธ ์ ๋ต์ ์ตํ๋ณด์ธ์.
- ๋จ์ด: 1,542๊ฐ20๋ถ
[๐ค] Tailwind CSS v4 ์ถ์: ๊ฐ๋ฐ์์๊ฒ ์ฐพ์์ฌ ๋ณํ์ ์ต์ ํ ์ ๋ต
Tailwind CSS v4์ ์ฃผ์ ๋ณ๊ฒฝ์ฌํญ๊ณผ ์๋ก์ด ๊ธฐ๋ฅ๋ค์ ๊น์ด ์๊ฒ ๋ถ์ํ๊ณ , ์ค๋ฌด์์ ํจ์จ์ ์ผ๋ก ์ ์ฉํ๋ฉฐ ์ฑ๋ฅ์ ์ต์ ํํ๋ ์ ๋ต์ ๋ธ๋ฃจ๊ฐ ์๋ ค๋๋ ค์.
- ๋จ์ด: 1,566๊ฐ20๋ถ
[๐ค] Next.js Dockerfile ์ต์ ํ: ํ๋ก๋์ ๋ฐฐํฌ๋ฅผ ์ํ ์๋ฒฝ ๊ฐ์ด๋
Next.js ์ ํ๋ฆฌ์ผ์ด์ ์ Docker ์ปจํ ์ด๋๋ก ํจ์จ์ ์ผ๋ก ๋ฐฐํฌํ๋ ๋ฐฉ๋ฒ์ ์์๋ณด์ธ์. ๋ฉํฐ์คํ ์ด์ง ๋น๋, ์บ์ฑ ์ ๋ต, ๋ณด์ ์ค์ ๋ฑ ํ๋ก๋์ ํ๊ฒฝ์ ์ต์ ํ๋ Dockerfile ์์ฑ ๊ฐ์ด๋๋ฅผ ์ ๊ณตํด ๋๋ ค์.
- ๋จ์ด: 2,177๊ฐ24๋ถ
[๐ค] CSS Grid ์ฌํ ๊ฐ์ด๋: ์ค์ ๋ ์ด์์ ํจํด๊ณผ ๋ฐ์ํ ๋์์ธ ์ ๋ต
CSS Grid๋ ๊ฐ๋ ฅํ 2์ฐจ์ ๋ ์ด์์ ์์คํ ์ด์์. ์ด ๊ฐ์ด๋์์ Grid์ ํต์ฌ ๊ฐ๋ ๋ถํฐ ์ค์ ๋ ์ด์์ ํจํด, ๋ฐ์ํ ๋์์ธ ์ ๋ต๊น์ง ์ฌ์ธต์ ์ผ๋ก ๋ค๋ฃจ์ด ์ค๋ฌด์ ๋ฐ๋ก ์ ์ฉํ ์ ์๋๋ก ๋์๋๋ ค์.
- ๋จ์ด: 1,718๊ฐ19๋ถ
[๐ค] TypeScript ํ ํ๋ฆฟ ๋ฆฌํฐ๋ด ํ์ : ๋ฌธ์์ด ํ์ ์ ๋ง๋ฒ์ฌ๋ก ๋ณ์ ํ๊ธฐ
TypeScript์ ํ ํ๋ฆฟ ๋ฆฌํฐ๋ด ํ์ ์ ํ์ฉํ์ฌ ๋ณต์กํ ๋ฌธ์์ด ํจํด์ ์์ ํ๊ฒ ํ์ ์ถ๋ก ํ๊ณ , ๊ฐ๋ ฅํ ์ ํธ๋ฆฌํฐ ํ์ ์ ๋ง๋๋ ๋ฐฉ๋ฒ์ ์ค๋ฌด ์์ ์ ํจ๊ป ์์ธํ ์์๋ด์. ํ์ ์์ ์ฑ์ ํ ๋จ๊ณ ๋์ฌ ๊ฐ๋ฐ ๊ฒฝํ์ ๊ฐ์ ํด ๋ณด์ธ์.
- ๋จ์ด: 1,918๊ฐ23๋ถ
[๐ค] JavaScript WeakMap๊ณผ WeakSet: ๋ฉ๋ชจ๋ฆฌ ๋์ ๋ฐฉ์ง์ ์ต์ ํ ์ ๋ต
JavaScript์์ WeakMap๊ณผ WeakSet์ ํ์ฉํ์ฌ ๋ฉ๋ชจ๋ฆฌ ๋์๋ฅผ ๋ฐฉ์งํ๊ณ ์ฑ๋ฅ์ ์ต์ ํํ๋ ๋ฐฉ๋ฒ์ ์ค์ฉ์ ์ธ ์์์ ํจ๊ป ์์ธํ ์์๋ด์. ๊ฐ๋น์ง ์ปฌ๋ ์ ๋์ ์๋ฆฌ์ ํจ๊ป ๊ฐ์ฒด ์ฐธ์กฐ ๊ด๋ฆฌ์ ์ค์์ฑ์ ์ดํดํ๊ณ , ์ค์ ํ๋ก์ ํธ์ ์ ์ฉํ๋ ์ ๋ต์ ๋ฐฐ์๋ด์.
- ๋จ์ด: 1,455๊ฐ17๋ถ
[๐ค] Next.js/React ํ๋ก์ ํธ๋ฅผ ์ํ ESLint & Prettier ์ค์ ์๋ฒฝ ๊ฐ์ด๋
๋ณต์กํ Next.js ๋ฐ React ํ๋ก์ ํธ์์ ์ผ๊ด๋ ์ฝ๋ ์คํ์ผ๊ณผ ํ์ง์ ์ ์งํ๋ ESLint์ Prettier ์ค์ ๋ฐฉ๋ฒ์ ์์ธํ ์๋ ค๋๋ ค์. ํ ๊ฐ๋ฐ ํ๊ฒฝ์ ์ต์ ํ๋ ์ค์ ์ผ๋ก ๊ฐ๋ฐ ํจ์จ์ ๋์ฌ๋ณด์ธ์.
- ๋จ์ด: 2,022๊ฐ25๋ถ
[๐ค] JavaScript์ ํต์ฌ: ํ๋กํ ํ์ ์ฒด์ธ ์๋ฒฝ ์ดํด์ ํ์ฉ ์ ๋ต
JavaScript์ ์ฌ์ฅ๋ถ, ํ๋กํ ํ์ ์ฒด์ธ์ ๋์ ์๋ฆฌ๋ฅผ ๊น์ด ํ๊ณ ๋ค์ด ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ๊ณผ ์์์ ์๋ฒฝํ๊ฒ ์ดํดํ๊ณ ์ค๋ฌด์ ์ ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์๋ณด์ธ์. ์ฑ๋ฅ ์ต์ ํ ํ๋ ํจ๊ป ๋ค๋ค์.
- ๋จ์ด: 2,118๊ฐ22๋ถ
[๐ค] React ์ปค์คํ ํ : ์ฌ์ฌ์ฉ์ฑ ๋์ด๋ ์ค๊ณ ์์น๊ณผ ํ ์คํธ ์ ๋ต
React ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ์ฌ์ฉ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ ๊ทน๋ํํ๋ ์ปค์คํ ํ ์ค๊ณ ์์น, ์ค์ฉ์ ์ธ ํจํด, ๊ทธ๋ฆฌ๊ณ ๊ฒฌ๊ณ ํ ํ ์คํธ ์ ๋ต์ ์๋์ด ๊ฐ๋ฐ์์ ๊ด์ ์์ ์์ธํ ์ค๋ช ํด ๋๋ ค์.
- ๋จ์ด: 2,107๊ฐ23๋ถ
[๐ค] React useRef ํ ์ฌ์ธต ๋ถ์: DOM ๋์ด์ ์ค์ ํ์ฉ ์ ๋ต
React useRef ํ ์ ๊ธฐ๋ณธ ์๋ฆฌ๋ถํฐ DOM ์์ ์ง์ ์ ์ด, ์ปดํฌ๋ํธ ๋ผ์ดํ์ฌ์ดํด ๊ด๋ฆฌ, ๊ทธ๋ฆฌ๊ณ ์ฑ๋ฅ ์ต์ ํ๋ฅผ ์ํ ๋ค์ํ ์ค์ ํ์ฉ ์ ๋ต๊น์ง ์ฌ์ธต์ ์ผ๋ก ๋ค๋ค์. ์ด์ค๊ธ ๊ฐ๋ฐ์๋ฅผ ์ํ useRef ์๋ฒฝ ๊ฐ์ด๋.
- ๋จ์ด: 1,762๊ฐ19๋ถ
[๐ค] Next.js 14/15์์ ๋์ OG ์ด๋ฏธ์ง ์์ฑ: ImageResponse ์๋ฒฝ ๊ฐ์ด๋
Next.js App Router ํ๊ฒฝ์์ ImageResponse๋ฅผ ํ์ฉํ์ฌ ๋์ OG ์ด๋ฏธ์ง๋ฅผ ํจ์จ์ ์ผ๋ก ์์ฑํ๋ ๋ฐฉ๋ฒ์ ์์๋ณด์ธ์. SEO์ ์์ ๊ณต์ ์ต์ ํ๋ฅผ ์ํ ์ค์ ๊ฐ์ด๋์ ๋๋ค.
- ๋จ์ด: 1,481๊ฐ18๋ถ
[๐ค] Git ๋ธ๋์น ์ ๋ต: Git Flow vs GitHub Flow, ์ค๋ฌด์์ ์ด๋ป๊ฒ ์ ํํ๊ณ ์ด์ํ ๊น์?
๊ฐ๋ฐํ์ ํจ์จ์ ์ธ ํ์ ์ ์ํ Git ๋ธ๋์น ์ ๋ต์ ๊ณ ๋ฏผํ๊ณ ๊ณ์ ๊ฐ์? Git Flow์ GitHub Flow์ ํต์ฌ ๊ฐ๋ ๋ถํฐ ์ฅ๋จ์ , ๊ทธ๋ฆฌ๊ณ ์ฐ๋ฆฌ ํ์ ๋ง๋ ์ ๋ต์ ์ ํํ๊ณ ์ด์ํ๋ ์ค์ง์ ์ธ ํ๊น์ง '๋ธ๋ฃจ'๊ฐ ์๋ ค๋๋ ค์.
- ๋จ์ด: 1,442๊ฐ16๋ถ
[๐ค] TypeScript ํ์ ๊ฐ๋: ๋ฐํ์ ํ์ ์์ ์ฑ์ ์ํ ํ์ ํจํด ์ ๋ณตํด์
TypeScript์์ ๋ฐํ์์ ๋ณ์์ ํ์ ์ ์์ ํ๊ฒ ์ขํ๋(Narrowing) ๋ฐฉ๋ฒ์ธ ํ์ ๊ฐ๋(Type Guard)์ ๋ํด ์์ธํ ์์๋ด์. `typeof`, `instanceof`, `in` ์ฐ์ฐ์๋ถํฐ ์ฌ์ฉ์ ์ ์ ํ์ ๊ฐ๋๊น์ง, ์ค์ฉ์ ์ธ ์์์ ํจ๊ป ๊ฒฌ๊ณ ํ ์ฝ๋๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ์ ์ตํ๋ด์.
- ๋จ์ด: 2,542๊ฐ28๋ถ
[๐ค] React Query (TanStack Query) ์ฌํ: ๋ฐ์ดํฐ ํ์นญ, ์บ์ฑ, ๋๊ธฐํ ์ ๋ต์ผ๋ก ์น ์ฑ ์ฑ๋ฅ ๊ทน๋ํํด์
React Query (TanStack Query)๋ฅผ ํ์ฉํ์ฌ ๋ณต์กํ ์๋ฒ ์ํ๋ฅผ ํจ์จ์ ์ผ๋ก ๊ด๋ฆฌํ๊ณ , ์ง๋ฅ์ ์ธ ์บ์ฑ๊ณผ ์๋ ๋๊ธฐํ ์ ๋ต์ผ๋ก ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฑ๋ฅ๊ณผ ์ฌ์ฉ์ ๊ฒฝํ์ ๊ทน๋ํํ๋ ๋ฐฉ๋ฒ์ ์ฌ์ธต์ ์ผ๋ก ๋ค๋ฃจ์ด์. useQuery, useMutation, useInfiniteQuery ๋ฑ ํต์ฌ ํ ๊ณผ ์ค์ ์ต์ ํ ํ์ ๋ฐฐ์๋ณด์ธ์.
- ๋จ์ด: 2,401๊ฐ26๋ถ
[๐ค] React `useTransition`๊ณผ `useDeferredValue`๋ก ์ฌ์ฉ์ ๊ฒฝํ์ ๊ทน๋ํํ๋ ๋ฐฉ๋ฒ
React ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ฌด๊ฑฐ์ด UI ์ ๋ฐ์ดํธ๋ก ์ธํ ๋ฒ๋ฒ ์์ ํด๊ฒฐํ๊ณ , `useTransition`๊ณผ `useDeferredValue` ํ ์ ํ์ฉํ์ฌ ์ฌ์ฉ์ ๊ฒฝํ์ ํ๊ธฐ์ ์ผ๋ก ๊ฐ์ ํ๋ ์ค์ฉ์ ์ธ ์ ๋ต์ ๋ฐฐ์๋ณด์ธ์.
- ๋จ์ด: 1,917๊ฐ22๋ถ
[๐ค] React Suspense์ ErrorBoundary: ๊ฒฌ๊ณ ํ๊ณ ๋ถ๋๋ฌ์ด UI ๊ฒฝํ์ ์ํ ์ค์ ๊ฐ์ด๋
React ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ฌ์ฉ์ ๊ฒฝํ์ ํ์ ํ Suspense์ ErrorBoundary์ ๊ฐ๋ ฅํ ์กฐํฉ์ ๊น์ด ์๊ฒ ๋ค๋ค์. ๋ก๋ฉ ์ํ์ ์๋ฌ ์ฒ๋ฆฌ๋ฅผ ์ฐ์ํ๊ฒ ๊ด๋ฆฌํ์ฌ ๋์ฑ ๊ฒฌ๊ณ ํ๊ณ ๋ถ๋๋ฌ์ด UI๋ฅผ ๋ง๋๋ ์ค์ ํ๊ณผ ์ฝ๋ ์์๋ฅผ ํ์ธํด ๋ณด์ธ์.
- ๋จ์ด: 1,302๊ฐ16๋ถ
[๐ค] CSS Container Queries: ์ปดํฌ๋ํธ ๊ธฐ๋ฐ ๋ฐ์ํ ๋์์ธ์ ์๋ก์ด ์งํ
๋ฏธ๋์ด ์ฟผ๋ฆฌ์ ํ๊ณ๋ฅผ ๋์ด, ์ปดํฌ๋ํธ ์์ฒด์ ํฌ๊ธฐ์ ๋ฐ๋ผ ์คํ์ผ์ ์กฐ์ ํ๋ CSS Container Queries๋ฅผ ๊น์ด ์๊ฒ ์์๋ณด๊ณ ์ค๋ฌด ์ ์ฉ ๋ฐฉ๋ฒ์ ์๋ดํด ๋๋ ค์.
- ๋จ์ด: 1,681๊ฐ19๋ถ
[๐ค] Next.js 15 ๊ณ ๊ธ ๋ฐ์ดํฐ ์บ์ฑ ์ ๋ต: fetch์ revalidate ์ฌ์ธต ๋ถ์
Next.js 15์์ `fetch` API์ ๊ฐ๋ ฅํ ์บ์ฑ ๋ฉ์ปค๋์ฆ๊ณผ `revalidate` ์ต์ ์ ํ์ฉํ์ฌ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฑ๋ฅ์ ์ต์ ํํ๊ณ ๋ฐ์ดํฐ๋ฅผ ํจ์จ์ ์ผ๋ก ๊ด๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ์ฌ์ธต์ ์ผ๋ก ๋ค๋ฃจ์ด์. ์ค๋ฌด ์์๋ฅผ ํตํด ์๋ฒ ์ปดํฌ๋ํธ์ ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ์์ ์บ์ฑ ์ ๋ต์ ํจ๊ณผ์ ์ผ๋ก ์ ์ฉํ๋ ํ์ ์ ๊ณตํด์.
๋จ์ด: 1,320๊ฐ14๋ถ[๐ค] Next.js App Router: generateStaticParams๋ก ๋์ ๋ผ์ฐํ ๋น๋ ์ต์ ํํ๊ธฐ
Next.js App Router์์ generateStaticParams ํจ์๋ฅผ ํ์ฉํ์ฌ ๋์ ๋ผ์ฐํ ์ ์ ์ ํ์ด์ง๋ฅผ ํจ์จ์ ์ผ๋ก ์์ฑํ๊ณ ๋น๋ ์ฑ๋ฅ์ ์ต์ ํํ๋ ๋ฐฉ๋ฒ์ ์ค์ฉ์ ์ธ ์์์ ํจ๊ป ์์ธํ ์์๋ด์.
๋จ์ด: 1,891๊ฐ22๋ถ[๐ค] React ๋ ๋๋ง ์ต์ ํ: useMemo, useCallback, React.memo ์๋ฒฝ ๊ฐ์ด๋
์ด์ค๊ธ ๊ฐ๋ฐ์๋ฅผ ์ํ React ๋ ๋๋ง ์ต์ ํ ๊ฐ์ด๋. useMemo, useCallback, React.memo์ ์ ํํ ์ฌ์ฉ๋ฒ๊ณผ ์ค๋ฌด์์ ํํ ์ ์ง๋ฅด๋ ์ค์, ๊ทธ๋ฆฌ๊ณ ์ค์ ์ฑ๋ฅ ํฅ์ ์ ๋ต์ ๋ธ๋ฃจ๊ฐ ์๋ ค๋๋ ค์.
๋จ์ด: 2,145๊ฐ24๋ถ[๐ค] JavaScript Proxy์ Reflect ์ฌ์ธต ๋ถ์: ๋ฉํ ํ๋ก๊ทธ๋๋ฐ์ผ๋ก ์ฝ๋ ๊ฐํํ๊ธฐ
JavaScript Proxy์ Reflect API๋ฅผ ํ์ฉํ ๋ฉํ ํ๋ก๊ทธ๋๋ฐ ๊ธฐ๋ฒ์ ์ฌ์ธต ๋ถ์ํด์. ๊ฐ์ฒด ์ ๊ทผ ์ ์ด, ์ ํจ์ฑ ๊ฒ์ฌ, ๋ก๊น , ๋ฐ์ํ ์์คํ ๊ตฌํ ๋ฑ ์ค์ฉ์ ์ธ ํ์ฉ ์ฌ๋ก๋ฅผ ํตํด ์ฝ๋์ ์ ์ฐ์ฑ๊ณผ ์์ ์ฑ์ ๋์ด๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์๋ณด์ธ์.
- ๋จ์ด: 2,029๊ฐ24๋ถ
[๐ค] React/Next.js ๋ฒ๋ค ์ต์ ํ: ์ฝ๋ ์คํ๋ฆฌํ ๊ณผ ๋ ์ด์ง ๋ก๋ฉ ์๋ฒฝ ๊ฐ์ด๋
React์ Next.js ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฒ๋ค ํฌ๊ธฐ๋ฅผ ์ค์ด๊ณ ๋ก๋ฉ ์๋๋ฅผ ๊ฐ์ ํ๋ ์ฝ๋ ์คํ๋ฆฌํ ๊ณผ ๋ ์ด์ง ๋ก๋ฉ ๊ธฐ๋ฒ์ ์ค์ฉ์ ์ธ ์์์ ํจ๊ป ์์ธํ ์์๋ด์. ์นํฉ ์ค์ ๋ถํฐ React.lazy, Next.js dynamic import๊น์ง ๋ค๋ค์.
- ๋จ์ด: 1,770๊ฐ20๋ถ
[๐ค] React์ `useOptimistic` ํ ์ผ๋ก ๋๊ด์ UI ์ ๋ฐ์ดํธ ๊ตฌํํ๊ธฐ: Server Actions์ ํจ๊ป
React 18/19์ `useOptimistic` ํ ์ ํ์ฉํ์ฌ Server Actions์ ์ฐ๋๋๋ ๋๊ด์ UI ์ ๋ฐ์ดํธ๋ฅผ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ์ค์ฉ์ ์ธ ์์์ ํจ๊ป ์์ธํ ์์๋ด์. ์ฌ์ฉ์ ๊ฒฝํ์ ๊ฐ์ ํ๊ณ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฐ์์ฑ์ ๋์ด๋ ๋ ธํ์ฐ๋ฅผ ๊ณต์ ํด์.
๋จ์ด: 1,561๊ฐ17๋ถ[๐ค] TypeScript const Type Parameters: ๋ฆฌํฐ๋ด ํ์ ์ถ๋ก ๊ฐํ์ ์ค์ฉ์ ์ธ ํ์ฉ๋ฒ
TypeScript 5.0์ ๋์ ๋ const Type Parameters๋ฅผ ํ์ฉํ์ฌ ์ ๋ค๋ฆญ ํจ์์ ๋ฆฌํฐ๋ด ํ์ ์ถ๋ก ์ ์ ๊ตํ๊ฒ ์ ์ดํ๊ณ , ๋์ฑ ๊ฒฌ๊ณ ํ ํ์ ์์คํ ์ ๊ตฌ์ถํ๋ ์ค์ฉ์ ์ธ ๋ฐฉ๋ฒ์ ์์๋ณด์ธ์. as const์์ ์ฐจ์ด์ ๊ณผ ์ค์ ์ฝ๋ ์์๋ฅผ ํตํด ์ด์ค๊ธ ๊ฐ๋ฐ์๋ ์ฝ๊ฒ ์ดํดํ ์ ์๋๋ก ์ค๋ช ํด ๋๋ ค์.
- ๋จ์ด: 2,028๊ฐ22๋ถ
[๐ค] Next.js/React ์ฑ CLS ์ต์ ํ: ์ํํธ ์๋ ์ฌ์ฉ์ ๊ฒฝํ ๋ง๋ค๊ธฐ
Next.js์ React ์ ํ๋ฆฌ์ผ์ด์ ์์ Cumulative Layout Shift(CLS) ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ณ ์ฌ์ฉ์ ๊ฒฝํ์ ๊ฐ์ ํ๋ ์ค์ง์ ์ธ ์ ๋ต๊ณผ ์ฝ๋ ์์๋ฅผ ์์ธํ ์์๋ณด์ธ์. ์น ์ฑ๋ฅ ์ต์ ํ์ ํต์ฌ ์์์ธ CLS๋ฅผ ํจ๊ณผ์ ์ผ๋ก ๊ด๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ์๋ ค๋๋ ค์.
- ๋จ์ด: 1,740๊ฐ21๋ถ
[๐ค] Next.js SSR, SSG, ISR ๋ ๋๋ง ์ ๋ต: App Router์์ ์ต์ ์ ์ ํ์?
Next.js App Router์์ ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง(SSR), ์ ์ ์ฌ์ดํธ ์์ฑ(SSG), ์ฆ๋ถ ์ ์ ์ฌ์์ฑ(ISR) ๊ฐ ๋ ๋๋ง ์ ๋ต์ ๋์ ์๋ฆฌ, ์ฅ๋จ์ , ์ค์ ํ์ฉ ๋ฐ ์ต์ ํ ๋ฐฉ๋ฒ์ ๋น๊ต ๋ถ์ํด๋๋ ค์.
- ๋จ์ด: 1,478๊ฐ17๋ถ
[๐ค] React Context API์ Zustand: ์ ์ญ ์ํ ๊ด๋ฆฌ, ์ธ์ ๋ฌด์์ ์จ์ผ ํ ๊น์?
React ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ์ญ ์ํ ๊ด๋ฆฌ๋ฅผ ๊ณ ๋ฏผํ๊ณ ๊ณ์ ๊ฐ์? Context API์ ๊ฐ๋ฒผ์ด ์ธ๋ถ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ธ Zustand๋ฅผ ๋น๊ต ๋ถ์ํ๊ณ , ์ค๋ฌด์์ ๊ฐ ๋๊ตฌ๋ฅผ ํจ๊ณผ์ ์ผ๋ก ํ์ฉํ๋ ์ ๋ต์ ์ค์ ์ฝ๋ ์์์ ํจ๊ป ์์ธํ ์๋ ค๋๋ ค์.
- ๋จ์ด: 2,004๊ฐ24๋ถ
[๐ค] Turborepo๋ก Next.js ๋ชจ๋ ธ๋ ํฌ ๊ตฌ์ถ: ํจ์จ์ ์ธ ๊ฐ๋ฐ ๋ฐ ์ต์ ํ ์ ๋ต
Turborepo๋ฅผ ํ์ฉํ์ฌ Next.js ํ๋ก์ ํธ๋ฅผ ๋ชจ๋ ธ๋ ํฌ๋ก ๊ตฌ์ฑํ๊ณ , ๊ณต์ ์ปดํฌ๋ํธ, ์ ํธ๋ฆฌํฐ, CI/CD ์ต์ ํ ๋ฐฉ์์ ์ค๋ฌด ์์์ ํจ๊ป ์์ธํ ์ค๋ช ํด ๋๋ ค์.
- ๋จ์ด: 2,338๊ฐ27๋ถ
[๐ค] React useEffect ํ , ์ด์ ํท๊ฐ๋ฆฌ์ง ๋ง์ธ์! (์์กด์ฑ ๋ฐฐ์ด, ํด๋ฆฐ์ ์๋ฒฝ ๊ฐ์ด๋)
React ๊ฐ๋ฐ์์ ํ์์ ์ธ useEffect ํ ์ ๋์ ์๋ฆฌ๋ถํฐ ์์กด์ฑ ๋ฐฐ์ด, ํด๋ฆฐ์ ํจ์ ํ์ฉ๋ฒ, ๊ทธ๋ฆฌ๊ณ ์ค๋ฌด์์ ์์ฃผ ๊ฒช๋ ์ค์์ ์ต์ ํ ์ ๋ต๊น์ง, ์ด์ค๊ธ ๊ฐ๋ฐ์๋ฅผ ์ํ ์๋ฒฝ ๊ฐ์ด๋๋ฅผ ์ ๊ณตํด์.
- ๋จ์ด: 3,284๊ฐ31๋ถ
[๐ค] Next.js Server Actions ์ค์ : ์๋ฌ ์ฒ๋ฆฌ, ์ ํจ์ฑ ๊ฒ์ฌ, ๋๊ด์ UI ์ ๋ฐ์ดํธ
Next.js Server Actions๋ฅผ ์ค๋ฌด์ ์ ์ฉํ ๋ ๋ง์ฃผํ๋ ์๋ฌ ์ฒ๋ฆฌ, ๋ฐ์ดํฐ ์ ํจ์ฑ ๊ฒ์ฌ, ๊ทธ๋ฆฌ๊ณ ์ฌ์ฉ์ ๊ฒฝํ์ ํฅ์์ํค๋ ๋๊ด์ UI ์ ๋ฐ์ดํธ ๊ธฐ๋ฒ์ ์์ธํ ์ฝ๋ ์์์ ํจ๊ป ์์๋ณด์ธ์.
๋จ์ด: 1,983๊ฐ21๋ถ[๐ค] TypeScript ์ ํธ๋ฆฌํฐ ํ์ ์๋ฒฝ ๊ฐ์ด๋: ์ค์ ํ์ฉ ํจํด
TypeScript ์ ํธ๋ฆฌํฐ ํ์ ์ ํต์ฌ ๊ฐ๋ ๊ณผ ์ค์ ํ์ฉ๋ฒ์ ๊น์ด ์๊ฒ ๋ค๋ค์. Pick, Omit, Partial, Required ๋ฑ ์์ฃผ ์ฐ๋ ์ ํธ๋ฆฌํฐ ํ์ ์ผ๋ก ๋ณต์กํ ํ์ ์ ํจ๊ณผ์ ์ผ๋ก ๋ค๋ฃจ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์๋ณด์ธ์. ํ์ ์คํฌ๋ฆฝํธ ์ฝ๋์ ์ฌ์ฌ์ฉ์ฑ๊ณผ ์์ ์ฑ์ ๋์ด๋ ๋ ธํ์ฐ๋ฅผ ๊ณต์ ํด์.
- ๋จ์ด: 1,712๊ฐ20๋ถ
[๐ค] Next.js App Router ๋ฏธ๋ค์จ์ด: ๊ฐ๋ ฅํ ์์ฒญ ์ฒ๋ฆฌ ์ ๋ต๊ณผ ์ค์ ์์
Next.js App Router ํ๊ฒฝ์์ ๋ฏธ๋ค์จ์ด๋ฅผ ํ์ฉํด ์ฌ์ฉ์ ์ธ์ฆ, ๋ฆฌ๋ค์ด๋ ์ , ๊ตญ์ ํ ๋ฑ์ ์์ฒญ ์ฒ๋ฆฌ ๋ก์ง์ ํจ์จ์ ์ผ๋ก ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ์ค์ ์์ ์ ํจ๊ป ์์ธํ ์์๋ณด์ธ์.
- ๋จ์ด: 1,630๊ฐ19๋ถ
[๐ค] ํ์ ์คํฌ๋ฆฝํธ ์ ๋ค๋ฆญ ์ฌํ: ์ค์ฉ์ ์ธ ํจํด๊ณผ ํํ ์คํด๋ค
ํ์ ์คํฌ๋ฆฝํธ ์ ๋ค๋ฆญ(Generics)์ ๊น์ด ์ดํดํ๊ณ , ์ค๋ฌด์์ ์์ฃผ ์ฌ์ฉ๋๋ ์ ๋ค๋ฆญ ํจํด๊ณผ ํํ ๊ฒช๋ ์คํด๋ค์ ์ค์ ์ฝ๋ ์์์ ํจ๊ป ์ฝ๊ณ ๋ช ํํ๊ฒ ์ค๋ช ํด ๋๋ ค์. ํ์ ์์ ์ฑ๊ณผ ์ฝ๋ ์ฌ์ฌ์ฉ์ฑ์ ๋์ด๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์๋ณด์ธ์.
๋จ์ด: 1,860๊ฐ18๋ถ[๐ค] Next.js Route Handler: App Router์์ ์์ ํ๊ณ ํจ์จ์ ์ธ API ๊ตฌ์ถํ๊ธฐ (์ธ์ฆ, ์๋ฌ ์ฒ๋ฆฌ ํฌํจ)
Next.js App Router์ Route Handler๋ฅผ ์ฌ์ฉํ์ฌ API ์๋ํฌ์ธํธ๋ฅผ ๊ตฌ์ถํ๋ ๋ฐฉ๋ฒ์ ์์ธํ ์์๋ด์. ์ธ์ฆ, ์๋ฌ ์ฒ๋ฆฌ, ๊ทธ๋ฆฌ๊ณ ์บ์ฑ ์ ๋ต์ ํฌํจํ ์ค์ฉ์ ์ธ ํ์ผ๋ก ์์ ํ๊ณ ํจ์จ์ ์ธ ์๋ฒ๋ฆฌ์ค ํจ์๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ์ ์ตํ๋ด์.
- ๋จ์ด: 1,934๊ฐ22๋ถ
[๐ค] Next.js Image ์ปดํฌ๋ํธ ์ต์ ํ: Core Web Vitals ๊ฐ์ ๋ถํฐ ์ค์ ํ์ฉ๊น์ง
Next.js์ Image ์ปดํฌ๋ํธ๋ฅผ ํ์ฉํ์ฌ ์น ์ฑ๋ฅ ํต์ฌ ์งํ์ธ Core Web Vitals๋ฅผ ๊ฐ์ ํ๊ณ , ๋ค์ํ ์ต์ ํ ์ต์ ์ ์ค์ ํ๋ก์ ํธ์ ์ ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ธ๋ฃจ๊ฐ ์์ธํ ์๋ ค๋๋ ค์.
- ๋จ์ด: 2,187๊ฐ25๋ถ
[๐ค] Next.js 14.1+์ ํ์ : Partial Prerendering (PPR) ์๋ฒฝ ๊ฐ์ด๋์ ์ค์ ์ต์ ํ ์ ๋ต
Next.js 14.1๋ถํฐ ๋์ ๋ Partial Prerendering (PPR)์ ํตํด ์ด๊ธฐ ๋ก๋ฉ ์๋๋ฅผ ๊ทน๋ํํ๊ณ ๋์ ์ฝํ ์ธ ๋ฅผ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ์ฌ๋ ์๊ฒ ๋ค๋ฃจ์ด์. PPR์ ๋์ ์๋ฆฌ๋ถํฐ ์ค์ ํ๋ก์ ํธ ์ ์ฉ ์ ๋ต๊น์ง, ๊ฐ๋ฐ์๋ค์ด ๊ถ๊ธํดํ๋ ๋ชจ๋ ๊ฒ์ ์๋ ค๋๋ ค์.
- ๋จ์ด: 1,792๊ฐ19๋ถ
[๐ค] TypeScript ์กฐ๊ฑด๋ถ ํ์ ๊ณผ infer ํค์๋: ๋ณต์กํ ํ์ ๋ ์์ฝ๊ฒ ๋ค๋ฃจ๋ ๋ฐฉ๋ฒ
TypeScript ๊ฐ๋ฐ์์ ๋ง์ฃผํ๋ ๋ณต์กํ ํ์ ์ถ๋ก ๋ฌธ์ , ์กฐ๊ฑด๋ถ ํ์ ๊ณผ infer ํค์๋๋ฅผ ํ์ฉํ๋ฉด ํจ์ฌ ์ฐ์ํ๊ณ ๊ฐ๋ ฅํ๊ฒ ํด๊ฒฐํ ์ ์์ด์. ์ค์ ์์ ์ ํจ๊ป ๊ทธ ํ์ฉ๋ฒ์ ์ฌ๋ ์๊ฒ ๋ค๋ค๋ด ๋๋ค.
- ๋จ์ด: 1,705๊ฐ21๋ถ
[๐ค] JavaScript ์ด๋ฒคํธ ๋ฃจํ(Event Loop) ์์ ์ ๋ณต: ๋น๋๊ธฐ ์ฒ๋ฆฌ์ ๋ฐํ์ ๋์ ์๋ฆฌ
JavaScript์ ํต์ฌ ๋น๋๊ธฐ ์ฒ๋ฆฌ ๋ฉ์ปค๋์ฆ์ธ ์ด๋ฒคํธ ๋ฃจํ์ ๋์ ์๋ฆฌ๋ฅผ ์ฌ๋ ์๊ฒ ํํค์ณ ๋ด์. ์ฝ ์คํ, ํ์คํฌ ํ, ๋ง์ดํฌ๋กํ์คํฌ ํ์์ ์ํธ์์ฉ์ ์ดํดํ๊ณ , ์ค๋ฌด์์ ๋ง์ฃผ์น๋ ๋น๋๊ธฐ ์ฝ๋์ ๋์์ ๋ช ํํ ์์ธกํ๋ ๋ฐฉ๋ฒ์ ์๋ ค๋๋ ค์.
- ๋จ์ด: 1,964๊ฐ23๋ถ
[๐ค] Next.js Server & Client Components, ์ค์ ์์ ํ๋ช ํ๊ฒ ์ ํํ๋ ๊ฐ์ด๋
Next.js App Router์์ Server Components์ Client Components ์ค ์ด๋ค ๊ฒ์ ์ฌ์ฉํด์ผ ํ ์ง ๊ณ ๋ฏผ์ด์ ๊ฐ์? ์ด ๊ธ์์ ๋ ์ปดํฌ๋ํธ์ ํต์ฌ ์ฐจ์ด์ , ์ฌ์ฉ ์์ , ๊ทธ๋ฆฌ๊ณ ์ฑ๋ฅ ์ต์ ํ๋ฅผ ์ํ ์ค์ ์ ๋ต์ ๋ธ๋ฃจ๊ฐ ์๋ ค๋๋ฆด๊ฒ์.
- ๋จ์ด: 1,879๊ฐ21๋ถ
[๐ค] TypeScript satisfies ์ฐ์ฐ์: ํ์ ์ถ๋ก ๊ณผ ์์ ์ฑ์ ๋์์ ์ก๋ ๋น๋ฒ
TypeScript์ `satisfies` ์ฐ์ฐ์๋ฅผ ํ์ฉํ์ฌ ํ์ ์ถ๋ก ์ ์ ์ฐ์ฑ์ ์ ์งํ๋ฉด์๋ ์๊ฒฉํ ํ์ ์์ ์ฑ์ ํ๋ณดํ๋ ๋ฐฉ๋ฒ์ ์์๋ณด์ธ์. ์ค์ฉ์ ์ธ ์์๋ฅผ ํตํด ์ค์ ํ๋ก์ ํธ์ ์ ์ฉํ๋ ๋ ธํ์ฐ๋ฅผ ๊ณต์ ํฉ๋๋ค.
- ๋จ์ด: 1,211๊ฐ15๋ถ
[๐ค] React 19 ์๋ก์ด ๊ธฐ๋ฅ: use ํ , Actions, ๊ทธ๋ฆฌ๊ณ ์ปดํ์ผ๋ฌ ๋ฏธ๋ฆฌ๋ณด๊ธฐ
React 19์ ํต์ฌ ๋ณ๊ฒฝ ์ฌํญ์ธ use ํ , ์๋ฒ ์ก์ , ๊ทธ๋ฆฌ๊ณ React ์ปดํ์ผ๋ฌ์ ๋์ ๋ฐฐ๊ฒฝ๊ณผ ์ค์ ํ์ฉ ์์๋ฅผ ์ด์ค๊ธ ๊ฐ๋ฐ์ ๋๋์ด์ ๋ง์ถฐ ์์ธํ ์ค๋ช ํฉ๋๋ค. ์ต์ React ์ ๋ฐ์ดํธ๋ฅผ ํตํด ์ ํ๋ฆฌ์ผ์ด์ ์ฑ๋ฅ๊ณผ ๊ฐ๋ฐ ๊ฒฝํ์ ํฅ์์ํค๋ ๋ฐฉ๋ฒ์ ์์๋ณด์ธ์.
- ๋จ์ด: 1,524๊ฐ16๋ถ
[๐ค] Next.js App Router ์บ์ฑ ์ ๋ต: ๋ฐ์ดํฐ ์ฌ๊ฒ์ฆ (revalidatePath, revalidateTag) ์๋ฒฝ ๊ฐ์ด๋
Next.js 14 App Router์์ ํจ์จ์ ์ธ ๋ฐ์ดํฐ ์บ์ฑ ์ ๋ต๊ณผ revalidatePath, revalidateTag๋ฅผ ์ด์ฉํ ๋ฐ์ดํฐ ์ฌ๊ฒ์ฆ ๋ฐฉ๋ฒ์ ์ค๋ฌด ์์์ ํจ๊ป ์์ธํ ์์๋ณด๊ณ ์น ์ฑ๋ฅ์ ์ต์ ํํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์๋ณด์ธ์.