[๐ค] TypeScript satisfies ์ฐ์ฐ์: ํ์ ์ถ๋ก ๊ณผ ์์ ์ฑ์ ๋์์ ์ก๋ ๋น๋ฒ
TypeScript์ `satisfies` ์ฐ์ฐ์๋ฅผ ํ์ฉํ์ฌ ํ์ ์ถ๋ก ์ ์ ์ฐ์ฑ์ ์ ์งํ๋ฉด์๋ ์๊ฒฉํ ํ์ ์์ ์ฑ์ ํ๋ณดํ๋ ๋ฐฉ๋ฒ์ ์์๋ณด์ธ์. ์ค์ฉ์ ์ธ ์์๋ฅผ ํตํด ์ค์ ํ๋ก์ ํธ์ ์ ์ฉํ๋ ๋ ธํ์ฐ๋ฅผ ๊ณต์ ํฉ๋๋ค.
์ ๋ณด๐ค ์ด ํฌ์คํ ์ Gemini 2.5 Flash AI๊ฐ ์์ฑํ์ด์.
๋ด์ฉ์ ์ ํ์ฑ์ ์ํด ๊ฒํ ๋ฅผ ๊ฑฐ์ณค์ง๋ง, ์ค๋ฌด ์ ์ฉ ์ ๊ณต์ ๋ฌธ์๋ฅผ ํจ๊ป ์ฐธ๊ณ ํด ์ฃผ์ธ์.
์ ์ฉํ ํTypeScript์
satisfies์ฐ์ฐ์๋ฅผ ์ฌ์ฉํ์ฌ ํ์ ์ถ๋ก ์ ์ ์ฐ์ฑ์ ์ ์งํ๋ฉด์๋ ์๊ฒฉํ ํ์ ์์ ์ฑ์ ํ๋ณดํ๋ ๋ฐฉ๋ฒ์ ์ค์ฉ์ ์ธ ์์์ ํจ๊ป ๋ฐฐ์๋ด ๋๋ค.
์๋
ํ์ธ์! 10๋
์ด์ ํ๋ก ํธ์๋์ ๋ฐฑ์๋๋ฅผ ๋๋๋ค๋ฉฐ ๊ฐ๋ฐํด ์จ ์๋์ด ๊ฐ๋ฐ์์
๋๋ค.
์ค๋์ ๋ง์ ๊ฐ๋ฐ์๋ถ๋ค์ด TypeScript๋ฅผ ์ฌ์ฉํ๋ฉด์ ํ ๋ฒ์ฏค์ ๊ณ ๋ฏผํด ๋ดค์ ๋ฒํ ๋ฌธ์ , ๋ฐ๋ก "ํ์
์ถ๋ก ์ ์ ์ฐ์ฑ๊ณผ ํ์
์์ ์ฑ์ ๋์์ ์ก๋ ๋ฐฉ๋ฒ"์ ๋ํด ์ด์ผ๊ธฐํด ๋ณด๋ ค๊ณ ํด์.
ํนํ TypeScript 4.9๋ถํฐ ๋์
๋ satisfies ์ฐ์ฐ์๊ฐ ์ด ๋ฌธ์ ๋ฅผ ์ด๋ป๊ฒ ์ฐ์ํ๊ฒ ํด๊ฒฐํด ์ฃผ๋์ง ์์ธํ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
0๏ธโฃ ํ์ ์ถ๋ก ์ ์ ์ฐ์ฑ๊ณผ ํ์ ์์ ์ฑ ์ฌ์ด์ ๋๋ ๋ง
TypeScript๋ ๊ฐ๋ ฅํ ํ์
์์คํ
์ ํตํด ๊ฐ๋ฐ ์์ฐ์ฑ๊ณผ ์ฝ๋ ์์ ์ฑ์ ๋์ฌ์ฃผ์ง๋ง, ๋๋ก๋ ํ์
์ ์ ๋ฐฉ์์ ๋ฐ๋ผ ๊ฐ๋ฐ ๊ฒฝํ์ด ๋ถํธํด์ง ๋๊ฐ ์์ด์.
์๋ฅผ ๋ค์ด, ์ด๋ค ๊ฐ์ฒด๊ฐ ํน์ ์ธํฐํ์ด์ค๋ฅผ ๋ง์กฑํด์ผ ํ์ง๋ง, ๋์์ ๊ทธ ๊ฐ์ฒด์ ๊ฐ๋ณ ํ๋กํผํฐ๋ ๋ ๊ตฌ์ฒด์ ์ธ ํ์
์ ์ ์งํ๊ณ ์ถ์ ๋๊ฐ ์์ต๋๋ค.
์๋ ์ฝ๋๋ฅผ ๋ณด์๊ฒ ์ด์?
type Colors = "red" | "green" | "blue"; interface Palette { primary: Colors; secondary: Colors; } // ๋ฌธ์ ์ํฉ: Palette ํ์ ์ ๋ช ์ํ๋ฉด, 'red'๋ string์ด ์๋๋ผ 'red' ๋ฆฌํฐ๋ด ํ์ ์ด์ด์ผ ํ๋๋ฐ... const myPalette: Palette = { primary: "red", secondary: "green", tertiary: "yellow", // Error: Object literal may only specify known properties }; // myPalette.primary๋ 'red' ๋ฆฌํฐ๋ด ํ์ ์ด ์๋๋ผ Colors ํ์ ์ด ๋์ด๋ฒ๋ ค์. const primaryColor = myPalette.primary; // type: Colors ('red' | 'green' | 'blue') // ๋ง์ฝ 'red' ๋ฆฌํฐ๋ด ํ์ ์ผ๋ก ์ฌ์ฉํ๊ณ ์ถ๋ค๋ฉด? // const specificColor: "red" = primaryColor; // Error: Type 'Colors' is not assignable to type '"red"'.
์ ์์์์ myPalette์ Palette ํ์
์ ๋ช
์ํ๋ฉด, tertiary ๊ฐ์ ์ถ๊ฐ ํ๋กํผํฐ๋ฅผ ๊ฐ์ง ์ ์๊ฒ ๋ฉ๋๋ค.
๋ํ, myPalette.primary๋ "red"๋ผ๋ ๊ตฌ์ฒด์ ์ธ ๋ฆฌํฐ๋ด ํ์
์ด ์๋ Colors ์ ๋์จ ํ์
์ผ๋ก ์ถ๋ก ๋์ด, ๋์ค์ "red" ๋ฆฌํฐ๋ด ํ์
์ด ํ์ํ ๊ณณ์ ์ง์ ํ ๋นํ๊ธฐ ์ด๋ ค์์ ธ์.
์ด๋ ํ์
์ถ๋ก ์ ์ ์ฐ์ฑ์ ์๊ฒ ๋ง๋๋ ๋ํ์ ์ธ ๊ฒฝ์ฐ์
๋๋ค.
1๏ธโฃ as ํค์๋์ ํ๊ณ์ ๋ฌธ์ ์
์ด๋ฐ ์ํฉ์์ ๋ง์ ๊ฐ๋ฐ์๋ถ๋ค์ด as ํค์๋๋ฅผ ์ฌ์ฉํด ๋ณด์
จ์ ๊ฑฐ์์.
as ํค์๋๋ ์ปดํ์ผ๋ฌ์๊ฒ "๋ด๊ฐ ๋ ์ ์๋, ์ด ํ์
์ ๋ฏฟ์ด์ค"๋ผ๊ณ ์ง์ํ๋ ์ญํ ์ ํฉ๋๋ค.
type Colors = "red" | "green" | "blue"; interface Palette { primary: Colors; secondary: Colors; } // 'as' ํค์๋ ์ฌ์ฉ ์์ const myPaletteWithAs = { primary: "red", secondary: "green", tertiary: "yellow", // ์ด ๋ถ๋ถ์ ์๋ฌ๊ฐ ๋์ง ์์์ (as Palette๊ฐ ์ ์ฒด๋ฅผ ๋ฎ์ด์์) } as Palette; // ํ์ง๋ง 'tertiary'๋ Palette ํ์ ์ ์์ผ๋ฏ๋ก ์ ๊ทผ ์ ์๋ฌ๊ฐ ๋ฐ์ํด์. // console.log(myPaletteWithAs.tertiary); // Error: Property 'tertiary' does not exist on type 'Palette'. // ๋ํ, myPaletteWithAs.primary๋ ์ฌ์ ํ Colors ํ์ ์ผ๋ก ์ถ๋ก ๋ฉ๋๋ค. const primaryColorFromAs = myPaletteWithAs.primary; // type: Colors
as ํค์๋๋ ๋ ๊ฐ์ง ๋ฌธ์ ๊ฐ ์์ต๋๋ค.
์ฒซ์งธ, ๊ฐ์ฒด ๋ฆฌํฐ๋ด์ ์๋ ํ๋กํผํฐ๋ฅผ ์ถ๊ฐํด๋ ์ปดํ์ผ ์์ ์ ์ค๋ฅ๋ฅผ ์ก์์ฃผ์ง ๋ชปํฉ๋๋ค.
as Palette๊ฐ ๊ฐ์ฒด ์ ์ฒด์ ์ ์ฉ๋๋ฉด์ tertiary ํ๋กํผํฐ์ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ๊ฑด๋๋ฐ๊ฒ ๋๋ ๊ฒ์ด์ฃ .
๋์งธ, ์ฌ์ ํ ๊ฐ๋ณ ํ๋กํผํฐ์ ๊ตฌ์ฒด์ ์ธ ๋ฆฌํฐ๋ด ํ์
์ ๋ณด๋ฅผ ์์ด๋ฒ๋ฆฌ๊ณ , ๋ช
์๋ ์ธํฐํ์ด์ค์ ์ ๋์จ ํ์
์ผ๋ก ์ถ๋ก ๋ฉ๋๋ค.
๊ฒฐ๊ณผ์ ์ผ๋ก as๋ ํ์
์์ ์ฑ์ ์ฝํ์ํค๊ฑฐ๋, ์ํ๋ ํ์
์ถ๋ก ์ ๋ฐฉํดํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์์.
0๏ธโฃ satisfies ์ฐ์ฐ์๋ ๋ฌด์์ธ๊ฐ์?
TypeScript 4.9๋ถํฐ ๋์
๋ satisfies ์ฐ์ฐ์๋ ์ด๋ฌํ ๋๋ ๋ง๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ํ์ํ์ด์.
satisfies๋ "์ด ํํ์์ด ํน์ ํ์
์ ์๊ตฌ์ฌํญ์ ๋ง์กฑํ๋์ง ํ์ธํ๋, ๊ทธ ํํ์์ ์๋ ์ถ๋ก ๋ ํ์
์ ๊ทธ๋๋ก ์ ์งํด ์ค"๋ผ๊ณ TypeScript ์ปดํ์ผ๋ฌ์๊ฒ ์ง์ํฉ๋๋ค.
์ฆ, ํ์
๊ฒ์ฌ๋ ์ํํ์ง๋ง, ํ์
์ถ๋ก ์ ๋ณ๊ฒฝํ์ง ์๋ ๊ฒ์ด์ฃ .
์ด๊ฒ์ as ํค์๋์๋ ๋งค์ฐ ๋ค๋ฅธ ์ ๊ทผ ๋ฐฉ์์ด์์.
as๋ ๊ฐ์ ๋ก ํ์
์ ๋ณ๊ฒฝํ๋ ๋ฐ๋ฉด, satisfies๋ ํ์
์ ๋ณ๊ฒฝํ์ง ์๊ณ ๋จ์ง "ํ์ธ"๋ง ํ๋ ์ญํ ์ ํฉ๋๋ค.
1๏ธโฃ as์ satisfies์ ๊ฒฐ์ ์ ์ธ ์ฐจ์ด
as์ satisfies์ ์ฐจ์ด๋ฅผ ๋ช
ํํ๊ฒ ์ดํดํ๋ ๊ฒ์ด ์ค์ํด์.
์ ๋ณด
as Type: "์ด ๊ฐ์Type์ผ๋ก ๊ฐ์ฃผํด ์ค. ๋ด๊ฐType์ด๋ผ๋ ๊ฒ์ ๋ณด์ฅํ ๊ฒ."-> ํ์ ์ ๊ฐ์ ๋ก ๋ณ๊ฒฝํ๊ณ , ์๋์ ์ธ๋ถ ํ์ ์ ๋ณด๋ฅผ ์์ ์ ์์ต๋๋ค. ์๋ชป ์ฌ์ฉํ๋ฉด ๋ฐํ์ ์ค๋ฅ๋ก ์ด์ด์ง ์ ์์ด์.
์ ์ฉํ ํ
satisfies Type: "์ด ๊ฐ์ดType์ ์๊ตฌ์ฌํญ์ ๋ง์กฑํ๋์ง ํ์ธํด ์ค. ํ์ง๋ง ์ด ๊ฐ์ ํ์ ์ ์๋ ์ถ๋ก ๋ ํ์ ๊ทธ๋๋ก ์ ์งํด ์ค."-> ํ์ ๊ฒ์ฌ๋ง ์ํํ๊ณ , ์๋์ ์ธ๋ถ ํ์ ์ ๋ณด๋ฅผ ๊ทธ๋๋ก ์ ์งํฉ๋๋ค. ํ์ ์์ ์ฑ์ ๋์ด๋ฉด์๋ ์ ์ฐํ ํ์ ์ถ๋ก ์ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค.
์ด์ satisfies๋ฅผ ์ฌ์ฉํ๋ฉด ์์์ ๋ฐ์ํ๋ ๋ฌธ์ ๋ค์ด ์ด๋ป๊ฒ ํด๊ฒฐ๋๋์ง ์ดํด๋ณด๊ฒ ์ต๋๋ค.
type Colors = "red" | "green" | "blue"; interface Palette { primary: Colors; secondary: Colors; } // satisfies ์ฐ์ฐ์ ์ฌ์ฉ ์์ const myPaletteSatisfies = { primary: "red", secondary: "green", // tertiary: "yellow" // Error: Object literal may only specify known properties. // -> satisfies๋ Palette ์ธํฐํ์ด์ค์ ์๋ ํ๋กํผํฐ๋ฅผ ์ถ๊ฐํ๋ฉด ์๋ฌ๋ฅผ ๋ฐ์์์ผ์! } satisfies Palette; // myPaletteSatisfies.primary๋ 'red' ๋ฆฌํฐ๋ด ํ์ ์ผ๋ก ์ถ๋ก ๋ฉ๋๋ค! const primaryColorFromSatisfies = myPaletteSatisfies.primary; // type: "red" // ์ด์ 'red' ๋ฆฌํฐ๋ด ํ์ ์ด ํ์ํ ๊ณณ์ ๋ฐ๋ก ์ฌ์ฉํ ์ ์์ด์. const specificColor: "red" = primaryColorFromSatisfies; // No Error! // ๊ฐ์ฒด ๋ฆฌํฐ๋ด์ ๋ค๋ฅธ ํ๋กํผํฐ๋ ์๋์ ๊ตฌ์ฒด์ ์ธ ํ์ ์ผ๋ก ์ถ๋ก ๋ฉ๋๋ค. const secondaryColorFromSatisfies = myPaletteSatisfies.secondary; // type: "green"
๋ณด์๋ ๊ฒ์ฒ๋ผ satisfies๋ฅผ ์ฌ์ฉํ๋ฉด Palette ์ธํฐํ์ด์ค์ ์กฐ๊ฑด์ ๋ง์กฑํ๋์ง ๊ฒ์ฌํ๋ฉด์๋, primary๊ฐ "red" ๋ฆฌํฐ๋ด ํ์
์ผ๋ก, secondary๊ฐ "green" ๋ฆฌํฐ๋ด ํ์
์ผ๋ก ์ ํํ๊ฒ ์ถ๋ก ๋๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
์ด๊ฒ์ด ๋ฐ๋ก satisfies ์ฐ์ฐ์์ ํต์ฌ์ ์ธ ๊ฐ์ ์ด์์!
satisfies ์ฐ์ฐ์๋ ๋ค์ํ ์ค์ ์๋๋ฆฌ์ค์์ ๋งค์ฐ ์ ์ฉํ๊ฒ ํ์ฉ๋ ์ ์์ด์.
๋ช ๊ฐ์ง ์ค์ ๊ฐ๋ฐ์์ ๋ง์ฃผํ ์ ์๋ ์์๋ฅผ ํตํด ๊ทธ ๊ฐ๋ ฅํจ์ ๋ ์์ธํ ์์๋ณด๊ฒ ์ต๋๋ค.
0๏ธโฃ ๊ฐ์ฒด ๋ฆฌํฐ๋ด์์ ์ธ๋ถ ํ๋กํผํฐ ํ์ ์ ์งํ๊ธฐ
์ด์ ์ ์ดํด๋ณธ Palette ์์์ ์ ์ฌํ๊ฒ, ์ค์ ๊ฐ์ฒด๋ ๋งคํ ๊ฐ์ฒด๋ฅผ ์ ์ํ ๋ ์ ์ฉํด์.
๊ฐ ํค์ ๊ฐ์ด ํน์ ์กฐ๊ฑด์ ๋ง์กฑํด์ผ ํ์ง๋ง, ๊ฐ ์์ฒด๋ ๋ ๊ตฌ์ฒด์ ์ธ ํ์
์ ์ ์งํ๊ณ ์ถ์ ๋ ์ฌ์ฉํฉ๋๋ค.
type LogLevel = "info" | "warn" | "error" | "debug"; interface LoggerConfig { level: LogLevel; format: string; } // ๊ฐ ํ๊ฒฝ๋ณ ์ค์ ์ ์ ์ํ๋ค๊ณ ๊ฐ์ ํด๋ด ์๋ค. const appConfigs = { development: { level: "debug", format: "[%level%] %message%", }, production: { level: "info", format: "[%level%] %timestamp% %message%", // maxFileSize: 1024 // Error: Object literal may only specify known properties. // -> LoggerConfig์ ์๋ ์์ฑ์ ์ถ๊ฐํ ์ ์์ต๋๋ค. }, test: { level: "error", format: "[%level%] %message%", }, } satisfies Record<string, LoggerConfig>; // Record<string, LoggerConfig>๋ฅผ ๋ง์กฑํ๋์ง ํ์ธ! // ์ด์ appConfigs.development.level์ "debug" ๋ฆฌํฐ๋ด ํ์ ์ผ๋ก ์ถ๋ก ๋ฉ๋๋ค. const devLogLevel = appConfigs.development.level; // type: "debug" // ํ๋ก๋์ ํ๊ฒฝ์ ํฌ๋งท์ ๊ฐ์ ธ์๋ string ๋ฆฌํฐ๋ด ํ์ ์ด ์ ์ง๋ฉ๋๋ค. const prodFormat = appConfigs.production.format; // type: "[%level%] %timestamp% %message%" // ๋ฐ๋ผ์ ์คํ ๋ฐฉ์ง ๋ฐ ์๋ ์์ฑ์๋ ํฐ ๋์์ด ๋ฉ๋๋ค. if (devLogLevel === "debug") { console.log("๋๋ฒ๊ทธ ๋ชจ๋์ ๋๋ค."); } // ๋ง์ฝ satisfies๋ฅผ ์ฌ์ฉํ์ง ์์๋ค๋ฉด devLogLevel์ LogLevel ํ์ ์ด ๋์์ ๊ฑฐ์์. // const devLogLevelWithoutSatisfies: LogLevel = appConfigs.development.level; // type: LogLevel
Record<string, LoggerConfig>๋ฅผ satisfies ํ๋ฉด, appConfigs ๊ฐ์ฒด ์ ์ฒด๊ฐ LoggerConfig์ ์กฐ๊ฑด์ ๋ง์กฑํ๋์ง ๊ฒ์ฌํฉ๋๋ค.
๋์์ appConfigs.development.level๊ณผ ๊ฐ์ ๊ฐ๋ณ ํ๋กํผํฐ๋ 'debug'์ ๊ฐ์ ๊ตฌ์ฒด์ ์ธ ๋ฆฌํฐ๋ด ํ์
์ผ๋ก ์ถ๋ก ๋์ด IntelliSense์ ํ์
์์ ์ฑ ๋ชจ๋๋ฅผ ํ๋ณดํ ์ ์์ด์.
1๏ธโฃ CSS ์์ฑ ์ ํจ์ฑ ๊ฒ์ฌ ๋ฐ ์๋ ์์ฑ ํ์ฉ
CSS-in-JS ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์คํ์ผ ๊ฐ์ฒด๋ฅผ ๋ค๋ฃฐ ๋ satisfies ์ฐ์ฐ์๋ ๋น์ ๋ฐํฉ๋๋ค.
ํน์ CSS ์์ฑ ์งํฉ์ ๋ง์กฑํ๋์ง ํ์ธํ๋ฉด์๋, ๊ฐ๋ฐ์๊ฐ ์ ์ํ ๊ฐ์ ๊ทธ๋๋ก ์ ์งํ๊ณ ์ถ์ ๋ ์ฌ์ฉํด์.
import React from "react"; type CSSProperties = React.CSSProperties; // ์ ํจํ ์์ ์ฝ๋๋ง ํ์ฉํ๋ ์ ํธ๋ฆฌํฐ ํ์ (์์) type HexColor = `#${string}`; type ValidColor = HexColor | "currentColor" | "transparent" | "inherit"; interface MyComponentStyle { container: CSSProperties & { backgroundColor?: ValidColor }; button: CSSProperties & { color?: ValidColor }; } const styles = { container: { display: "flex", padding: "16px", backgroundColor: "#f0f0f0", // HexColor๋ฅผ ๋ง์กฑํ๋์ง ๊ฒ์ฌ // invalidColor: "not-a-color" // Error: Object literal may only specify known properties }, button: { color: "currentColor", fontSize: "16px", fontWeight: "bold", // hoverColor: "#123" // Error: Object literal may only specify known properties }, } satisfies MyComponentStyle; // styles.container.backgroundColor๋ "#f0f0f0" ๋ฆฌํฐ๋ด ํ์ ์ผ๋ก ์ถ๋ก ๋ฉ๋๋ค. const containerBg = styles.container.backgroundColor; // type: "#f0f0f0" // ์ด๋ฅผ ํตํด ์ ํํ ํ์ ์ ๋ณด๋ฅผ ํ์ฉํ ์ ์์ต๋๋ค. const specificBg: "#f0f0f0" = containerBg; // No Error! // ๋ง์ฝ ์คํ๊ฐ ์๋ค๋ฉด ์ฆ์ ์๋ฌ๋ฅผ ๋ฐ์์์ผ์. // styles.container.backgroundColour; // Error: Property 'backgroundColour' does not exist on type '{ display: string; padding: string; backgroundColor: "#f0f0f0"; }'.
styles ๊ฐ์ฒด๊ฐ MyComponentStyle์ satisfies ํ๋์ง ๊ฒ์ฌํจ์ผ๋ก์จ, ์๋ชป๋ CSS ์์ฑ์ด๋ ์ ํจํ์ง ์์ ์์ ๊ฐ์ ์ฌ์ฉํ๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
๋์์ backgroundColor์ ๊ฐ์ ์์ฑ๋ค์ "#f0f0f0"์ ๊ฐ์ ๊ตฌ์ฒด์ ์ธ ๋ฌธ์์ด ๋ฆฌํฐ๋ด ํ์
์ผ๋ก ์ถ๋ก ๋์ด, ๋์ค์ ์ด ๊ฐ์ ํ์ฉํ ๋ ๋ ์ ํํ ํ์
์ ๋ณด๋ฅผ ์ป์ ์ ์์ด์.
2๏ธโฃ ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋๋ ์ฝ๋ฐฑ ํจ์ ํ์ ์์ ํ๊ฒ ์ ์ํ๊ธฐ
ํจ์ ๋งค๊ฐ๋ณ์๋ ๋ฐํ ๊ฐ์ ๋ํ ํ์
์ ์ ์ํ ๋๋ satisfies๋ฅผ ํ์ฉํ ์ ์์ด์.
ํน์ ์ธํฐํ์ด์ค๋ฅผ ๋ง์กฑํ๋ ํจ์๋ฅผ ์ ์ํ๋ฉด์๋, ํจ์์ ๋ด๋ถ ๊ตฌํ์์ ์ฌ์ฉ๋๋ ๋งค๊ฐ๋ณ์๋ ๋ก์ปฌ ๋ณ์์ ํ์
์ ๋ ๊ตฌ์ฒด์ ์ผ๋ก ์ ์งํ๊ณ ์ถ์ ๋ ์ ์ฉํฉ๋๋ค.
type EventName = "click" | "hover" | "focus"; interface EventHandler { (event: { type: EventName; target: HTMLElement }): void; } const eventHandlers = { handleClick: (event) => { // event.type์ "click" ๋ฆฌํฐ๋ด ํ์ ์ผ๋ก ์ถ๋ก ๋ฉ๋๋ค! if (event.type === "click") { console.log("ํด๋ฆญ ์ด๋ฒคํธ ๋ฐ์:", event.target); } }, handleHover: (event) => { // event.type์ "hover" ๋ฆฌํฐ๋ด ํ์ ์ผ๋ก ์ถ๋ก ๋ฉ๋๋ค! console.log("ํธ๋ฒ ์ด๋ฒคํธ ๋ฐ์:", event.target.tagName); // event.target.focus(); // Error: Property 'focus' does not exist on type 'HTMLElement'. // -> HTMLElement์ focus๊ฐ ์์ผ๋ฉด ์๋ฌ ๋ฐ์ (ํ์ ์์ ์ฑ ๋ณด์ฅ) }, } satisfies Record<string, EventHandler>; // eventHandlers.handleClick์ event ๋งค๊ฐ๋ณ์ ํ์ ์ { type: "click"; target: HTMLElement }๋ก ์ถ๋ก ๋ฉ๋๋ค. // ์ด๋ Record<string, EventHandler>์ ์ ์ฝ์ ๋ง์กฑํ๋ฉด์๋, ๊ฐ ํธ๋ค๋ฌ์ ๊ตฌ์ฒด์ ์ธ ํ์ ์ ๋ณด๋ฅผ ์ ์งํ๊ฒ ํด์ค๋๋ค. // ์ด ํธ๋ค๋ฌ๋ฅผ ์ฌ์ฉํ ๋๋ ํ์ ์์ ์ฑ์ ๋๋ฆด ์ ์์ด์. const myButton = document.createElement("button"); myButton.addEventListener("click", (e) => { eventHandlers.handleClick({ type: "click", target: e.currentTarget as HTMLElement, }); });
์ฌ๊ธฐ์ eventHandlers ๊ฐ์ฒด๊ฐ Record<string, EventHandler>๋ฅผ satisfies ํ๋์ง ๊ฒ์ฌํจ์ผ๋ก์จ, ๋ชจ๋ ํธ๋ค๋ฌ ํจ์๊ฐ EventHandler ์ธํฐํ์ด์ค์ ์กฐ๊ฑด์ ๋ง์กฑํ๋์ง ํ์ธํฉ๋๋ค.
๋์์ handleClick ํจ์ ๋ด๋ถ์ event.type์ "click" ๋ฆฌํฐ๋ด ํ์
์ผ๋ก, handleHover ํจ์ ๋ด๋ถ์ event.type์ "hover" ๋ฆฌํฐ๋ด ํ์
์ผ๋ก ์ ํํ๊ฒ ์ถ๋ก ๋ฉ๋๋ค.
์ด๋ฅผ ํตํด ๊ฐ๋ฐ์๋ ๊ฐ ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ๋ก์ง์ ์์ฑํ ๋ ๋ ๊ตฌ์ฒด์ ์ธ ํ์
์ ๋ณด๋ฅผ ํ์ฉํ ์ ์๊ฒ ๋์ด ์์ฐ์ฑ๊ณผ ์์ ์ฑ ๋ชจ๋๋ฅผ ๋์ผ ์ ์์ด์.
0๏ธโฃ ์ฃผ์ ์ฅ์
satisfies ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ์ฅ์ ๋ค์ ์ป์ ์ ์์ต๋๋ค.
- ํ์
์์ ์ฑ ํ๋ณด: ํน์ ํ์
์ ์กฐ๊ฑด์ ๋ง์กฑํ๋์ง ์ปดํ์ผ ์์ ์ ๊ฒ์ฌํ์ฌ ์ ์ฌ์ ์ธ ์ค๋ฅ๋ฅผ ๋ฐฉ์งํด์.
์๋ฅผ ๋ค์ด,Palette์์์์tertiary๊ฐ์ ๋ถํ์ํ ํ๋กํผํฐ ์ถ๊ฐ๋ฅผ ๋ง์์ค๋๋ค. - ํ์
์ถ๋ก ์ ์ฐ์ฑ ์ ์ง: ๊ฐ์ ์๋ ์ถ๋ก ๋ ํ์
์ ๊ทธ๋๋ก ์ ์งํ์ฌ, ๋ ๊ตฌ์ฒด์ ์ธ ํ์
์ ๋ณด๋ฅผ ํ์ฉํ ์ ์์ด์.
"red"์ ๊ฐ์ ๋ฆฌํฐ๋ด ํ์ ์ ์์ง ์์ IntelliSense์ ์ฝ๋์ ์ ํ์ฑ์ ๋์ฌ์ค๋๋ค. - ๋ถํ์ํ ํ์
๋จ์ธ(
as) ๊ฐ์:asํค์๋๋ฅผ ๋จ์ฉํ ํ์๊ฐ ์์ด ์ฝ๋์ ๊ฐ๋ ์ฑ์ ๋์ด๊ณ ,as๋ก ์ธํ ์ ์ฌ์ ์ธ ๋ฐํ์ ์ค๋ฅ๋ฅผ ์ค์ฌ์ค๋๋ค. - ์๋ ์์ฑ ๋ฐ ๋ฆฌํฉํ ๋ง ์ฉ์ด: ๊ตฌ์ฒด์ ์ธ ํ์ ์ ๋ณด๊ฐ ์ ์ง๋๋ฏ๋ก ๊ฐ๋ฐ ๋๊ตฌ์ ์๋ ์์ฑ ๊ธฐ๋ฅ์ด ๋์ฑ ๊ฐ๋ ฅํด์ง๊ณ , ์ฝ๋ ๋ฆฌํฉํ ๋ง ์์๋ ํ์ ์ค๋ฅ๋ฅผ ์ฝ๊ฒ ๊ฐ์งํ ์ ์์ด์.
1๏ธโฃ ์ฌ์ฉ ์ ์ฃผ์ํ ์
satisfies ์ฐ์ฐ์๋ ๊ฐ๋ ฅํ์ง๋ง, ๋ช ๊ฐ์ง ์ฃผ์ํ ์ ๋ ์์ต๋๋ค.
- TypeScript 4.9 ์ด์์์๋ง ์ฌ์ฉ ๊ฐ๋ฅ:
satisfies๋ TypeScript 4.9 ๋ฒ์ ๋ถํฐ ๋์ ๋ ๊ธฐ๋ฅ์ด๋ฏ๋ก, ํ๋ก์ ํธ์ TypeScript ๋ฒ์ ์ ํ์ธํด์ผ ํฉ๋๋ค.
๊ตฌํ ๋ฒ์ ์์๋ ์ฌ์ฉํ ์ ์์ด์. - ์ค๋ฒํค๋ ๋ฐ์ ๊ฐ๋ฅ์ฑ: ๋งค์ฐ ๋ณต์กํ ํ์
์ ์์ ๋๊ท๋ชจ ๊ฐ์ฒด์
satisfies๋ฅผ ๊ณผ๋ํ๊ฒ ์ฌ์ฉํ๋ฉด ์ปดํ์ผ ์๊ฐ์ด ์ฝ๊ฐ ๋์ด๋ ์ ์์ต๋๋ค.
ํ์ง๋ง ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ์ฑ๋ฅ ์ ํ๋ ๋ฏธ๋ฏธํ๋ฉฐ, ์ป๋ ์ด์ ์ด ํจ์ฌ ์ปค์. as์ ๋์ฒด์ฌ๋ ์๋:satisfies๊ฐas์ ๋ง์ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ๋์ฒดํ ์ ์์ง๋ง,as๋ ์ฌ์ ํ ํน์ ์ํฉ(์: ํ์ ๊ฐ๋๋ฅผ ์ฐํํด์ผ ํ๋ ๋๋ฌธ ๊ฒฝ์ฐ)์์ ํ์ํ ์ ์์ต๋๋ค.
๊ฐ ํค์๋์ ๋ชฉ์ ์ ์ ํํ ์ดํดํ๊ณ ์ ์ ํ๊ฒ ์ฌ์ฉํ๋ ๊ฒ์ด ์ค์ํด์.
๐ ์ ๋ฆฌํ๋ฉฐ
0๏ธโฃ ํต์ฌ ์์ฝ
์ค๋์ TypeScript์ satisfies ์ฐ์ฐ์์ ๋ํด ์์ธํ ์์๋ณด์์ต๋๋ค.
satisfies๋ ๊ฐ์ ํ์
์ด ํน์ ์ธํฐํ์ด์ค๋ ํ์
์ ์กฐ๊ฑด์ ๋ง์กฑํ๋์ง ๊ฒ์ฌํ๋ฉด์๋, ๊ฐ ์์ฒด์ ๊ตฌ์ฒด์ ์ธ ํ์
์ถ๋ก ์ ๊ทธ๋๋ก ์ ์งํ๋ ํ์ ์ ์ธ ๋ฐฉ๋ฒ์ด์์.
์ด๋ฅผ ํตํด ๊ฐ๋ฐ์๋ค์ ํ์
์์ ์ฑ์ ํด์น์ง ์์ผ๋ฉด์๋ ์ ์ฐํ๊ณ ์ ํํ ํ์
์ ๋ณด๋ฅผ ํ์ฉํ ์ ์๊ฒ ๋ฉ๋๋ค.
as ํค์๋๊ฐ ๊ฐ์ง ์ ์๋ ์ ์ฌ์ ์ธ ์ํ์ ํํผํ๊ณ , ๋ ์์ ํ๊ณ ๊ฐ๋ ฅํ ํ์
์์คํ
์ ๊ตฌ์ถํ๋ ๋ฐ satisfies ์ฐ์ฐ์๊ฐ ํฐ ๋์์ด ๋ ๊ฑฐ์์.
1๏ธโฃ ๋ค์ ๋จ๊ณ๋ก ๋์๊ฐ๊ธฐ
์ด์ ์ฌ๋ฌ๋ถ์ ํ๋ก์ ํธ์ satisfies ์ฐ์ฐ์๋ฅผ ์ ์ฉํด ๋ณผ ์๊ฐ์
๋๋ค!
์ค์ ๊ฐ์ฒด, ์คํ์ผ ๊ฐ์ฒด, ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ฑ ๋ค์ํ ์ํฉ์์ satisfies๋ฅผ ํ์ฉํ์ฌ ์ฝ๋์ ์์ ์ฑ๊ณผ ๊ฐ๋ฐ ์์ฐ์ฑ์ ํ ๋จ๊ณ ๋ ๋์ฌ๋ณด์ธ์.
๊ถ๊ธํ ์ ์ด๋ ๋ ๋
ผ์ํ๊ณ ์ถ์ ๋ถ๋ถ์ด ์๋ค๋ฉด ์ธ์ ๋ ์ง ๋๊ธ๋ก ๋จ๊ฒจ์ฃผ์ธ์.
ํจ๊ป ์ฑ์ฅํ๋ ๊ฐ๋ฐ ๋ฌธํ์ ๊ธฐ์ฌํ ์ ์๋๋ก ๋
ธ๋ ฅํ๊ฒ ์ต๋๋ค!
๐ฎ ์ฐธ๊ณ
- TypeScript 4.9 Release Notes - The
satisfiesoperator - Understanding TypeScript's
satisfiesoperator - React.CSSProperties
์ฐ๊ด๋ ํฌ์คํธ
- ๋จ์ด: 1,541๊ฐ20๋ถ
[๐ค] Tailwind CSS v4 ์ถ์: ๊ฐ๋ฐ์์๊ฒ ์ฐพ์์ฌ ๋ณํ์ ์ต์ ํ ์ ๋ต
Tailwind CSS v4์ ์ฃผ์ ๋ณ๊ฒฝ์ฌํญ๊ณผ ์๋ก์ด ๊ธฐ๋ฅ๋ค์ ๊น์ด ์๊ฒ ๋ถ์ํ๊ณ , ์ค๋ฌด์์ ํจ์จ์ ์ผ๋ก ์ ์ฉํ๋ฉฐ ์ฑ๋ฅ์ ์ต์ ํํ๋ ์ ๋ต์ ๋ธ๋ฃจ๊ฐ ์๋ ค๋๋ ค์.
- ๋จ์ด: 1,563๊ฐ20๋ถ
[๐ค] Next.js Dockerfile ์ต์ ํ: ํ๋ก๋์ ๋ฐฐํฌ๋ฅผ ์ํ ์๋ฒฝ ๊ฐ์ด๋
Next.js ์ ํ๋ฆฌ์ผ์ด์ ์ Docker ์ปจํ ์ด๋๋ก ํจ์จ์ ์ผ๋ก ๋ฐฐํฌํ๋ ๋ฐฉ๋ฒ์ ์์๋ณด์ธ์. ๋ฉํฐ์คํ ์ด์ง ๋น๋, ์บ์ฑ ์ ๋ต, ๋ณด์ ์ค์ ๋ฑ ํ๋ก๋์ ํ๊ฒฝ์ ์ต์ ํ๋ Dockerfile ์์ฑ ๊ฐ์ด๋๋ฅผ ์ ๊ณตํด ๋๋ ค์.
- ๋จ์ด: 2,161๊ฐ24๋ถ
[๐ค] CSS Grid ์ฌํ ๊ฐ์ด๋: ์ค์ ๋ ์ด์์ ํจํด๊ณผ ๋ฐ์ํ ๋์์ธ ์ ๋ต
CSS Grid๋ ๊ฐ๋ ฅํ 2์ฐจ์ ๋ ์ด์์ ์์คํ ์ด์์. ์ด ๊ฐ์ด๋์์ Grid์ ํต์ฌ ๊ฐ๋ ๋ถํฐ ์ค์ ๋ ์ด์์ ํจํด, ๋ฐ์ํ ๋์์ธ ์ ๋ต๊น์ง ์ฌ์ธต์ ์ผ๋ก ๋ค๋ฃจ์ด ์ค๋ฌด์ ๋ฐ๋ก ์ ์ฉํ ์ ์๋๋ก ๋์๋๋ ค์.
- ๋จ์ด: 1,716๊ฐ19๋ถ
[๐ค] TypeScript ํ ํ๋ฆฟ ๋ฆฌํฐ๋ด ํ์ : ๋ฌธ์์ด ํ์ ์ ๋ง๋ฒ์ฌ๋ก ๋ณ์ ํ๊ธฐ
TypeScript์ ํ ํ๋ฆฟ ๋ฆฌํฐ๋ด ํ์ ์ ํ์ฉํ์ฌ ๋ณต์กํ ๋ฌธ์์ด ํจํด์ ์์ ํ๊ฒ ํ์ ์ถ๋ก ํ๊ณ , ๊ฐ๋ ฅํ ์ ํธ๋ฆฌํฐ ํ์ ์ ๋ง๋๋ ๋ฐฉ๋ฒ์ ์ค๋ฌด ์์ ์ ํจ๊ป ์์ธํ ์์๋ด์. ํ์ ์์ ์ฑ์ ํ ๋จ๊ณ ๋์ฌ ๊ฐ๋ฐ ๊ฒฝํ์ ๊ฐ์ ํด ๋ณด์ธ์.
- ๋จ์ด: 1,917๊ฐ23๋ถ
[๐ค] JavaScript WeakMap๊ณผ WeakSet: ๋ฉ๋ชจ๋ฆฌ ๋์ ๋ฐฉ์ง์ ์ต์ ํ ์ ๋ต
JavaScript์์ WeakMap๊ณผ WeakSet์ ํ์ฉํ์ฌ ๋ฉ๋ชจ๋ฆฌ ๋์๋ฅผ ๋ฐฉ์งํ๊ณ ์ฑ๋ฅ์ ์ต์ ํํ๋ ๋ฐฉ๋ฒ์ ์ค์ฉ์ ์ธ ์์์ ํจ๊ป ์์ธํ ์์๋ด์. ๊ฐ๋น์ง ์ปฌ๋ ์ ๋์ ์๋ฆฌ์ ํจ๊ป ๊ฐ์ฒด ์ฐธ์กฐ ๊ด๋ฆฌ์ ์ค์์ฑ์ ์ดํดํ๊ณ , ์ค์ ํ๋ก์ ํธ์ ์ ์ฉํ๋ ์ ๋ต์ ๋ฐฐ์๋ด์.
- ๋จ์ด: 1,446๊ฐ17๋ถ
[๐ค] Next.js/React ํ๋ก์ ํธ๋ฅผ ์ํ ESLint & Prettier ์ค์ ์๋ฒฝ ๊ฐ์ด๋
๋ณต์กํ Next.js ๋ฐ React ํ๋ก์ ํธ์์ ์ผ๊ด๋ ์ฝ๋ ์คํ์ผ๊ณผ ํ์ง์ ์ ์งํ๋ ESLint์ Prettier ์ค์ ๋ฐฉ๋ฒ์ ์์ธํ ์๋ ค๋๋ ค์. ํ ๊ฐ๋ฐ ํ๊ฒฝ์ ์ต์ ํ๋ ์ค์ ์ผ๋ก ๊ฐ๋ฐ ํจ์จ์ ๋์ฌ๋ณด์ธ์.
- ๋จ์ด: 2,006๊ฐ25๋ถ
[๐ค] JavaScript์ ํต์ฌ: ํ๋กํ ํ์ ์ฒด์ธ ์๋ฒฝ ์ดํด์ ํ์ฉ ์ ๋ต
JavaScript์ ์ฌ์ฅ๋ถ, ํ๋กํ ํ์ ์ฒด์ธ์ ๋์ ์๋ฆฌ๋ฅผ ๊น์ด ํ๊ณ ๋ค์ด ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ๊ณผ ์์์ ์๋ฒฝํ๊ฒ ์ดํดํ๊ณ ์ค๋ฌด์ ์ ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์๋ณด์ธ์. ์ฑ๋ฅ ์ต์ ํ ํ๋ ํจ๊ป ๋ค๋ค์.
- ๋จ์ด: 2,087๊ฐ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,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๋ฅผ ์ด์ฉํ ๋ฐ์ดํฐ ์ฌ๊ฒ์ฆ ๋ฐฉ๋ฒ์ ์ค๋ฌด ์์์ ํจ๊ป ์์ธํ ์์๋ณด๊ณ ์น ์ฑ๋ฅ์ ์ต์ ํํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์๋ณด์ธ์.