Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що робить хук useId()?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`useId()`** створює унікальний, стабільний ідентифікатор, який React гарантує однаковим і на сервері (при SSR), і на клієнті (при гідратації). **Ключове:** це потрібно для зв'язування елементів форм (`label` і `input`), генерації `aria-*` атрибутів для доступності і будь-яких інших випадків, де `Math.random()` чи `uuid()` дали б різні значення на сервері й клієнті та зламали гідратацію.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Що робить `useId()` > `useId()` створює **унікальний, стабільний ідентифікатор** (ID), > який React гарантує **однаковим**: > > - на сервері (при SSR), > - і на клієнті (при гідратації). Це потрібно для: - зв'язування елементів форм (наприклад, `<label>` і `<input>`), - генерації `id` у списках, де не можна використовувати індекс, - створення унікальних `aria-*` атрибутів для доступності (A11y), - генерації ідентифікаторів у компонентах, що рендеряться багаторазово. --- ## Синтаксис ```javascript const id = useId(); ``` `useId()` повертає **рядок** (наприклад: `"react-aria123"`), який **гарантовано унікальний** у рамках усього застосунку. React гарантує: - унікальність усередині дерева компонентів; - стабільність між рендерами; - передбачуваний збіг між **сервером і клієнтом** при SSR. --- ## Приклад використання ### Правильне зв'язування `label` і `input`: ```javascript function NameField() { const id = useId(); return ( <div> <label htmlFor={id}>Ім'я:</label> <input id={id} type="text" /> </div> ); } ``` Чому це важливо: - Якби ти використовував `Math.random()` або UUID, на сервері й клієнті вийшли б **різні значення**, і при **гідратації** React видав би попередження: ```javascript Warning: Prop `id` did not match. Server: "a123" Client: "b456" ``` З `useId()` такого не відбувається - React синхронізує ID. --- ## Як React робить ID узгодженими React при рендерингу формує ID на основі **детермінованого префікса і лічильника**, а не випадкового числа. Приклад результату: ```javascript id = react-aria123 id = react-aria124 id = react-aria125 ``` І ці значення будуть **однаковими**: - при серверному рендерингу (`renderToString()` / `renderToPipeableStream()`), - при гідратації на клієнті (`hydrateRoot()`). --- ## Приклад з кількома елементами ```javascript function EmailForm() { const emailId = useId(); const passwordId = useId(); return ( <form> <label htmlFor={emailId}>Email</label> <input id={emailId} type="email" /> <label htmlFor={passwordId}>Пароль</label> <input id={passwordId} type="password" /> </form> ); } ``` Кожен виклик `useId()` створює **новий ID**, але стабільний між рендерами. --- ## Порівняння з іншими способами | Метод | Проблема | |---|---| | `Math.random()` | Різні значення між сервером і клієнтом -> hydration warning | | `uuid()` | Випадковий результат -> порушує детермінізм SSR | | Лічильник у компоненті | Може збитися при умовному рендері | | `useId()` | Детермінований, унікальний, SSR-friendly | --- ## Вкладені компоненти `useId()` добре працює навіть у вкладених компонентах, тому що React створює **ієрархічні префікси**, щоб уникнути колізій між компонентами. Приклад: ```javascript function FormField({ label, children }) { const id = useId(); return ( <div> <label htmlFor={id}>{label}</label> {React.cloneElement(children, { id })} </div> ); } function Form() { return ( <FormField label="Ім'я"> <input type="text" /> </FormField> ); } ``` React створить **унікальний, вкладений ID**, щоб колізій не було: ```javascript react-aria1-1 react-aria1-2 react-aria2-1 ``` --- ## Спільне використання з CSS / aria Часто `useId()` застосовують для атрибутів доступності: ```javascript function Tooltip({ text, children }) { const tooltipId = useId(); return ( <> {React.cloneElement(children, { 'aria-describedby': tooltipId })} <span id={tooltipId} role="tooltip"> {text} </span> </> ); } ``` Доступно, унікально і без колізій навіть при SSR. --- ## Обмеження 1. `useId()` не можна використовувати **всередині циклів / умов**, інакше порядок викликів хуків порушиться (як і в будь-якого React-хука). 2. Не призначений для **динамічних унікальних ключів** у списках. Для ключів у `map()` як і раніше потрібно використовувати унікальні ідентифікатори з даних. 3. Не підходить для генерації **глобальних UUID** - це інструмент лише для **стабільних ID усередині React-дерева**. --- ## Підсумок > `useId()` - це хук для генерації **унікальних, стабільних і детермінованих ідентифікаторів**, > однакових між **сервером і клієнтом**, що робить його незамінним при: > > - SSR + Hydration, > - формуванні зв'язків `label` ↔ `input`, > - роботі з aria-атрибутами і доступністю, > - вкладених компонентах, що повторюються. --- ### Коротко: | Властивість | Значення | |---|---| | Повертає | Унікальний рядок ID | | Стабільність | Між рендерами і між сервером/клієнтом | | Сумісність з SSR | Так | | Унікальність у дереві | Гарантована | | Можна використовувати в циклі | Ні | | Працює з | React 18+ | | Типові сценарії | Форми, aria, SSR, вкладені компоненти |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.