UseId в React: связь label, поля и подсказки без повторяющихся ID

UseId в React: связь label, поля и подсказки без повторяющихся ID
Содержание статьи

У двух экземпляров поля формы не должно быть одного жёстко заданного id. Хук useId помогает создать идентификатор для связей доступности внутри компонента. В практикуме Mentoring.digital соберём поле с подписью и пояснением.

Свяжите три элемента одним базовым ID

import { useId } from "react";

function EmailField({ label }) {
  const baseId = useId();
  const hintId = `${baseId}-hint`;

  return (
    <div>
      <label htmlFor={baseId}>{label}</label>
      <input id={baseId} type="email"
        aria-describedby={hintId} />
      <p id={hintId}>Укажите адрес для ответа.</p>
    </div>
  );
}

HtmlFor у label указывает на id поля. Aria-describedby у input указывает на отдельный элемент с подсказкой. Для нескольких связанных элементов можно получить один базовый ID и добавить понятные суффиксы.

Вызовите компонент дважды, например для основного и дополнительного адреса. У каждого экземпляра будут свои связи. Не нужно передавать один и тот же постоянный идентификатор всем полям.

Проверьте поведение формы

Нажатие на подпись должно переводить фокус в соответствующее поле. Проверьте отдельно обе подписи: ошибка с повторяющимся id часто проявляется тем, что фокус всегда попадает в первый input.

Затем пройдите форму клавишей Tab. Для проверки доступного имени и описания используйте дерево доступности браузера или подходящий инструмент чтения с экрана. Наличие атрибута само по себе не доказывает, что весь пользовательский сценарий формы доступен.

Пример отвечает только за идентификаторы. Он не добавляет сохранение данных, обработку отправки или проверку бизнес-правил. Эти части формы нужно проектировать и проверять отдельно.

Не подменяйте ID идентификатором данных

UseId вызывается на верхнем уровне компонента или собственного хука. Его нельзя помещать в условие или цикл. Если список содержит много полей, вынесите отдельное поле в компонент и вызывайте хук внутри него.

Не используйте useId для key элементов списка. Key должен происходить из данных и помогать React сопоставлять элементы при изменении списка. Идентификатор связи label и input решает другую задачу.

При серверном рендеринге дерево компонентов на сервере и клиенте должно согласовываться. Если на странице несколько независимых корней React, предусмотрите разные identifierPrefix, а для гидратации одного корня сохраняйте одинаковый префикс с обеих сторон.

Задание: добавьте вторую подсказку об ошибке с суффиксом error и продумайте, когда её ID попадает в aria-describedby. Затем проверьте форму с двумя экземплярами поля. Такой компонент можно разобрать на практическом курсе React и обсудить с ментором по React.

Похожие статьи по данной теме