Guía profunda sobre React Key

Guía profunda sobre React Key

En algún momento hemos tenido el mismo error en la consola: Warning: Each child in an array or operator should have a unique "key" prop. También se nos han ocurrido diferentes maneras de solventar este error. Sin embargo, ¿sabes exactamente qué ocurre si asignamos un valor aleatorio, índice o identificador? ¿Hay alguna diferencia?

¿Cómo funciona key prop?

Para averiguar las diferencias que existen entre los distintos posibles valores como key prop, es necesario saber cómo funciona el key prop detrás de escenas. Key es una prop que React nos recuerda agregar para identificar cada elemento de un listado.

Por consiguiente, este valor debe ser único con respecto a los demás. La key prop es de vital importancia porque, según ello, React deberá ejecutar el proceso de re-render. Para ello sigue un simple algoritmo con el cual ejecutarlo:

1) Se crean snapshots del item (before y after).

2) Identifica los ítems que ya se encontraban en la página para usarlos.

  • En caso de que tengan los mismos keys, no es necesario crearlos.
  • Si los ítems no tienen key, entonces se asigna el valor según el índice. Sin embargo, React lanza un warning en consola si omitimos agregar key (Warning: Each child in an array or operator should have a unique "key" prop).

3) Finalmente,

  • Se eliminan los ítems que estaban en “before”, pero que no se encuentran en “after” (unmount).
  • Se agregan los ítems que no estaban en “before”, pero que sí se muestran en “after” (mount).
  • Se actualizan los ítems que se encuentran en ambas fases “before” y “after” (re-render).

El algoritmo nos ayuda a comprender cuándo se ejecuta el re-render. La siguiente pregunta es acerca del valor que le asignemos a key-prop. Hay diferencias si asignamos un valor aleatorio, índice e identificador.

Aleatorios como key

Supongamos que asignamos como key valores aleatorios a una lista de componentes. ¿Qué sucede? ¡A simple vista funciona! Sin embargo, tiene un impacto en el desempeño de nuestra app.

El eliminar (unmount) y agregar un componente (mount) tiene un impacto en el performance de nuestra app. Los valores aleatorios como key son una mala idea. ¡Debemos evitarlos!

En el siguiente código se puede visualizar mejor. Ingresa al enlace donde se muestran las veces que se montan y desmontan los componentes.

Índices como key

Es muy usual que usemos los índices de los array como key. Veamos los resultados que obtenemos. Cuando usamos el índice de nuestro array resolvemos el problema de unmount y mount que teníamos con valores aleatorios. De esta manera, no hay errores de desempeño. ¡Genial!

https://codesandbox.io/s/react-key-item-with-index-3gyj0o?file=/src/App.tsx:32-49

Identificadores como Key

Usar un identificador es una práctica común y que debemos emplear cuando se pueda. No necesitamos obtener el índice de nuestro array.

https://codesandbox.io/s/react-key-item-with-id-forked-qhz4ys

En ambos casos, índices e identificadores como key, es necesario ejecutar re-render. ¿Existe alguna manera de evitarlo? Sí, con un memo en nuestros componentes. Eso sí, solo evitaremos el re-render si usamos identificadores como keys. ¿Por qué?

Usar memo en índices como key

Sabemos cuál memo ejecuta el re-render solo cuando las props del componente cambian. Al ordenar los componentes, los índices persisten en ambos snapshots. Sin embargo, las props no se mantienen con el índice del before snapshot.

Usar memo en identificadores como key

A diferencia de usar los índices, no es necesario que React ejecute re-render. Lo único que varía en los snapshots (before y after) es el orden de los componentes.

Ahora, si los componentes tienen un estado sucede un comportamiento extraño.

Componentes con un estado

En el siguiente ejemplo, cada uno de los componentes cambia de color al hacer clic. Para ello, es necesario un estado (useState).

https://codesandbox.io/s/react-key-id-index-random-forked-hqtq67?file=/src/ListItem.tsx

Hagamos clic en el segundo ítem y luego en el botón de ordenamiento. Sucede lo siguiente:

1) Se crean los snapshots “before” y “after”.

2) Verificación de si existe el key y recuperación de las instancias respectivas. Tengamos en cuenta que, al recuperar las instancias, el key y estado del componente están asociados.

  • ID como key: recupera la instancia según el key (en ambos snapshots existen los mismos keys).
  • Index como Key: recupera la instancia según el key (en ambos snapshots existen los mismos keys).
  • Aleatorio como key: los keys son distintos en ambos snapshots.

3) Mount, unmount y re-render

  • ID como key: en la instancia con el key 2 (segundo ítem) persiste el estado y se ejecuta el re-render. Sin embargo, al usar memo no se ejecutará el re-render.
  • Index como key: la instancia con el key 1 (segundo ítem) está asociada al estado y siempre el segundo ítem permanecerá seleccionado. En esta ocasión, el re-render sí se ejecuta debido a que nuestra key está basada en el index del array y las props cambiaron.
  • Aleatorio como key: las keys no existen en el snapshot after. Así que se remueven (unmount) y agregan los nuevos (mount).

Finalmente

  1. No es buena práctica asignar valores aleatorios como Key.
  2. Usar hook memo en nuestros ítems solucionará re-render y mejorará el desempeño de nuestro componente.
  3. Usar el ID del registro en listas dinámicas (agregar, filtrar o reordenar) evitará bugs y re-renders.
  4. Podemos usar index como key en caso de que no necesitemos ejecutar una operación (filtrar, agregar, reordenar) sobre la lista o los ítems no cuenten con un estado. Caso ejemplo: paginación.

Espero que esta lista haya sido de utilidad para ti. ¡Nos vemos pronto!

⚠️
Las opiniones y comentarios emitidos en este artículo son propiedad única de su autor y no necesariamente representan el punto de vista de Revelo.

Revelo Content Network da la bienvenida a todas las razas, etnias, nacionalidades, credos, géneros, orientaciones, puntos de vista e ideologías, siempre y cuando promuevan la diversidad, la equidad, la inclusión y el crecimiento profesional de los profesionales en tecnología.