๐Ÿ”‘ React์—์„œ useId๋ž€ ๋ฌด์—‡์ธ๊ฐ€?

๋ฐœํ–‰: (2025๋…„ 12์›” 28์ผ ์˜ค์ „ 07:54 GMT+9)
3 min read
์›๋ฌธ: Dev.to

Source: Dev.to

useId๋Š” React(๋ฒ„์ „โ€ฏ18๋ถ€ํ„ฐ ์‚ฌ์šฉ ๊ฐ€๋Šฅ)์—์„œ ์ œ๊ณตํ•˜๋Š” Hook์œผ๋กœ, ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ ๊ณ ์œ ํ•˜๊ณ  ์•ˆ์ •์ ์ธ ์‹๋ณ„์ž๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด Hook์€ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•ด ์œ ์ผํ•œ ๋ฌธ์ž์—ด์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

useId๋Š” ๋ฌด์—‡์„ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋‚˜์š”?

์š”์†Œ ์—ฐ๊ฒฐ (์ ‘๊ทผ์„ฑ)

๊ฐ€์žฅ ํ”ํ•œ ์‚ฌ์šฉ ์‚ฌ๋ก€๋Š” <label>์„ ํผ ํ•„๋“œ( <input> )์™€ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. HTML์—์„œ๋Š” label์˜ htmlFor ์†์„ฑ์ด input์˜ id ์†์„ฑ๊ณผ ๋™์ผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ID๋ฅผ ์ˆ˜๋™์œผ๋กœ ์ฝ”๋”ฉํ•˜๊ณ  ์ปดํฌ๋„ŒํŠธ๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ๋ Œ๋”๋งํ•˜๋ฉด ์ค‘๋ณต๋œ ID๊ฐ€ ๋ฐœ์ƒํ•ด HTML์ด ๋ฌดํšจํ™”๋˜๊ณ  ์Šคํฌ๋ฆฐ ๋ฆฌ๋”๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋™์ž‘ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

useId๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ์˜ ๊ฐ ์ธ์Šคํ„ด์Šค๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅธ ID๋ฅผ ๋ฐ›์•„, label๊ณผ input ์‚ฌ์ด์˜ ์˜ฌ๋ฐ”๋ฅธ ์—ฐ๊ฒฐ์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.

import { useId } from 'react';

function PasswordField() {
  // ์ด ์ธ์Šคํ„ด์Šค๋ฅผ ์œ„ํ•œ ๊ณ ์œ ํ•˜๊ณ  ์•ˆ์ •์ ์ธ ID ์ƒ์„ฑ
  const passwordId = useId();

  return (
    <>
      Senha:
      {/* ID ์‚ฌ์šฉ ์˜ˆ์‹œ */}
      <label htmlFor={passwordId}>Senha</label>
      <input id={passwordId} type="password" />
    </>
  );
}

Serverโ€‘Side Rendering(SSR) ํ˜ธํ™˜์„ฑ

useId๋Š” ์„œ๋ฒ„์—์„œ ์ตœ์ดˆ ๋ Œ๋”๋ง๋  ๋•Œ ์ƒ์„ฑ๋œ ID์™€ ํด๋ผ์ด์–ธํŠธ์—์„œ์˜ ํ›„์† ๋ Œ๋”๋ง(ํ•˜์ด๋“œ๋ ˆ์ด์…˜) ์‹œ ์ƒ์„ฑ๋œ ID๊ฐ€ ๋™์ผํ•˜๋„๋ก ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋ฌด์ž‘์œ„ ๋˜๋Š” ๋น„๊ฒฐ์ •์ ์œผ๋กœ ์ƒ์„ฑ๋œ ID๋กœ ์ธํ•ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ถˆ์ผ์น˜๋ฅผ ๋ฐฉ์ง€ํ•˜๊ณ , ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ ๊ฐ„ HTML ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.

๊ธฐํƒ€ ARIA ์†์„ฑ

์ด Hook์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ARIA ์ ‘๊ทผ์„ฑ ์†์„ฑ์—๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • aria-labelledby
  • aria-describedby

์–ธ์ œ useId๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์•ˆ ๋ ๊นŒ?

  • ๋ฆฌ์ŠคํŠธ ํ‚ค ์ƒ์„ฑ: ๋ฆฌ์ŠคํŠธ(.map())์˜ key๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ID์™€ ๊ฐ™์ด ์•ˆ์ •์ ์ธ ๊ฐ’์— ๊ธฐ๋ฐ˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. useId๋Š” ๋ฆฌ์ŠคํŠธ ์ˆœ์„œ๊ฐ€ ๋ฐ”๋€” ๋•Œ ์•ˆ์ •์„ฑ์„ ๋ณด์žฅํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์ƒํƒœ ๋ฒ„๊ทธ๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ „์—ญ์ ์œผ๋กœ ๊ณ ์œ ํ•œ ID(UUID) ์ƒ์„ฑ: useId๊ฐ€ React ํŠธ๋ฆฌ ๋‚ด์—์„œ๋Š” ๊ณ ์œ ํ•˜์ง€๋งŒ, ๊ทธ ํ˜•์‹์€ ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ ๊ฐ„ ์ผ๊ด€์„ฑ์„ ์œ„ํ•ด ๊ฒฐ์ •๋ก ์ ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ฌด์ž‘์œ„ UUID์™€ ๊ฐ™์€ ์ „์—ญ ๊ณ ์œ  ์‹๋ณ„์ž๋กœ ์‚ฌ์šฉํ•ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค.
Back to Blog

๊ด€๋ จ ๊ธ€

๋” ๋ณด๊ธฐ ยป

Show HN: Phantas โ€“ ๋ธŒ๋ผ์šฐ์ € ๊ธฐ๋ฐ˜ ๋ฐ”์ด๋…ธ๋Ÿด ์ŠคํŠธ๋กœ๋ธŒ ์—”์ง„ (Web Audio API)

์•ˆ๋…•ํ•˜์„ธ์š” HN, ์ €๋Š” Aphantasia(์ •์‹  ์ด๋ฏธ์ง€๊ฐ€ ์—†๋Š”) ์ƒˆ๋กœ์šด ๊ฐœ๋ฐœ์ž์ž…๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ๋ฐฉํ•ด๋ฅผ ๋ฐ›์€ ๋’ค ๋‹ค์‹œ ์ง‘์ค‘ํ•˜๋Š” ๋ฐ ์˜ค๋žœ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ๋ฉฐ, ์•ฝ 23๋ถ„ ์ •๋„ ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค.

๐ŸŒŸ eslint-plugin-jsx-a11y๋ž€ ๋ฌด์—‡์ธ๊ฐ€?

eslintโ€‘pluginโ€‘jsxโ€‘a11y๊ฐ€ ๋ฌด์—‡์ธ๊ฐ€์š”? ์ด๊ฒƒ์€ ESLint ํ”Œ๋Ÿฌ๊ทธ์ธ์œผ๋กœ, JSX ์ฝ”๋“œ์— ๋Œ€ํ•œ ์ •์  ๋ถ„์„์„ ์ˆ˜ํ–‰ํ•˜์—ฌ ์ ‘๊ทผ์„ฑ ๊ทœ์น™ ์ง‘ํ•ฉ์„ ์‹๋ณ„ํ•˜๊ณ  ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.

์œ„๋Œ€ํ•œ ํ”„๋ก ํŠธ์—”๋“œ ์ „ํ™˜: 2026๋…„๊นŒ์ง€ React์—์„œ Angular๋กœ

์œ„๋Œ€ํ•œ ํ”„๋ก ํŠธ์—”๋“œ ์ „ํ™˜: React โ†’ Angular 2026 ํ”„๋ก ํŠธ์—”๋“œ ํ™˜๊ฒฝ์ด ๊ธ‰๊ฒฉํ•œ ๋ณ€ํ™”๋ฅผ ๊ฒช๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฑฐ์˜ 10๋…„๊ฐ„ React๊ฐ€ ์ง€๋ฐฐํ•œ ๋’ค, Angular๊ฐ€ โ€ฆ

React๋ž€ ๋ฌด์—‡์ธ๊ฐ€?

!What is React?์— ๋Œ€ํ•œ ํ‘œ์ง€ ์ด๋ฏธ์ง€ https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amaz...