useId es un Hook de React para generar IDs unicos que se puede pasar a los atributos de accesibilidad.

const id = useId()

Uso

Atención

No utilices useId para generar keys en una lista. Las keys deben generarse a partir de sus datos.

Generación de ID únicos para atributos de accesibilidad

Llame a useId en el nivel superior de su componente para generar una ID única:

import { useId } from 'react';

function PasswordField() {
const passwordHintId = useId();
// ...

A continuación, puedes pasar el ID generado a los diferentes atributos:

<>
<input type="password" aria-describedby={passwordHintId} />
<p id={passwordHintId}>
</>

Veamos un ejemplo para ver cuándo es útil.

Atrbutos de accesibilidad HTML como aria-describedby le permite especificar que dos etiquetas están relacionadas entre sí. Por ejemplo, puede especificar que un determinado elemento (como una entrada) sea descrito por otro elemento (como un párrafo).

En HTML normal, lo escribirías así:

<label>
Password:
<input
type="password"
aria-describedby="password-hint"
/>
</label>
<p id="password-hint">
The password should contain at least 18 characters
</p>

Sin embargo, utliziar identificaciones como este no es una buena práctica en React. Un componente puede representarse más de una vez en la página, ¡pero las ID tienen que ser únicas! En lugar de utliziar una ID, puede generar una ID única con useId:

import { useId } from 'react';

function PasswordField() {
const passwordHintId = useId();
return (
<>
<label>
Password:
<input
type="password"
aria-describedby={passwordHintId}
/>
</label>
<p id={passwordHintId}>
The password should contain at least 18 characters
</p>
</>
);
}

Ahora, incluso si PasswordField aparece varias veces en la pantalla, las identificaciones generadas no chocarán.

import { useId } from 'react';

function PasswordField() {
  const passwordHintId = useId();
  return (
    <>
      <label>
        Password:
        <input
          type="password"
          aria-describedby={passwordHintId}
        />
      </label>
      <p id={passwordHintId}>
        The password should contain at least 18 characters
      </p>
    </>
  );
}

export default function App() {
  return (
    <>
      <h2>Choose password</h2>
      <PasswordField />
      <h2>Confirm password</h2>
      <PasswordField />
    </>
  );
}

Mira este video para ver la diferencia en la experiencia del usuario con tecnologías de asistencia.

Atención

useId requiere un árbol de componentes idéntico en el servidor y el cliente cuando cuando utiliza server rendering. Si los árboles que se representan en el servidor y el cliente no coinciden exactamente, las ID generadas no coincidirán.

Deep Dive

Por qué useId es mejor que un contador incremental?

Quizás se pregunte por qué useId es mejor que incrementar una variable global como nextId++.

El principal beneficio de useId es que React asegura que funciona con server rendering. Durante el server rendering, sus componentes generan salida HTML. Mas tarde, en el cliente hydrate adjunta sus controladores de eventos al HTML generado. Para que la hidratación funcione, la salida del cliente debe coincidir con el HTML del servidor.

Esto es muy difícil de garantizar con un contador incremental porque el orden en que se hidratan los componentes del cliente puede no coincidir con el orden en que se emitió el HTML del servidor. Al llamar a useId, te aseguras de que la hidratación funcionará y la salida coincidirá entre el servidor y el cliente.

Dentro de React, useId se genera a partir de la “ruta principal” del componente llamado. Esta es la razón por la que, si el cliente y el árbol del servidor son iguales, la “ruta principal” coincidirá independientemente del orden de representación.


Si necesita proporcionar ID a varios elementos relacionados, puede llamar a useId para generar un prefijo compartido para ellos:

import { useId } from 'react';

export default function Form() {
  const id = useId();
  return (
    <form>
      <label htmlFor={id + '-firstName'}>First Name:</label>
      <input id={id + '-firstName'} type="text" />
      <hr />
      <label htmlFor={id + '-lastName'}>Last Name:</label>
      <input id={id + '-lastName'} type="text" />
    </form>
  );
}

Esto le permite evitar llamar a useId para cada elemento que necesita una identificación única.


Especificación de un prefijo compartido para todas las ID generadas

Si renderiza varias aplicaciones React independientes en una sola página, puede pasar identifierPrefix como una opción para las llamadas createRoot o hydrateRoot. Esto garantiza que los ID generados por las dos aplicaciones diferentes nunca entren en conflicto porque cada identificador generado con useId comenzará con el prefijo distinto que haya especificado.

import { createRoot } from 'react-dom/client';
import App from './App.js';
import './styles.css';

const root1 = createRoot(document.getElementById('root1'), {
  identifierPrefix: 'my-first-app-'
});
root1.render(<App />);

const root2 = createRoot(document.getElementById('root2'), {
  identifierPrefix: 'my-second-app-'
});
root2.render(<App />);


Referencia

useId()

Llame a useId en el nivel superior de su componente para generar una ID única:

import { useId } from 'react';

function PasswordField() {
const passwordHintId = useId();
// ...

Vea más ejemplos arriba.

Parametros

useId no toma ningún parámetro.

Retorna

useId devuelve una cadena de ID única asociada con esta llamada useId llamado en un componente particular.

Advertencias

  • useId es un Hook, así que solo puedes llamarlo en el nivel superior de su componente o en tus propios hooks. No puedes llamarlo dentro de bucles o condiciones. Si lo necesita, extraiga un nuevo componente y mueva el estado a él.

  • useId no debe usarse para generar keys en una lista. Las keys deben generarse a partir de sus datos.