25

Dominando las keys en React.js: aprende cómo implementarlas

49094Puntos

hace un año

Para manejar listas en React, es obligatorio agregar una prop key con valores únicos e irrepetibles en cada elemento que se renderiza. ¿Por qué no es recomendable utilizar el índice de una lista como clave? Averigüémoslo.

El detalle con el Virtual DOM

Es bien sabido que React necesita un Virtual DOM para poder hacer cambios en su árbol de nodos. Todo esto sucede gracias a un algoritmo de diferenciación, que debe ser lo más eficiente posible para que pueda cambiar solo las partes necesarias y no toda nuestra aplicación.

Al aplicar las keys en nuestras listas, React puede entender mejor cuándo ocurre lo siguiente:

  • Identificar cuando agregamos elementos.
  • Reconocer cuando un elemento se actualiza.
  • Determinar cuando removemos un elemento.

Al tener un ID único para cada elemento, permitimos que React haga cambios solo en ese elemento en lugar de toda la aplicación.

Pongamos a prueba el prop key

Para que este concepto quede aún más claro, haremos un pequeño ejercicio en el que crearemos una lista empleando el ID proporcionado por el método map y luego lo cambiaremos por un ID único.

const App = () => {
  // Vamos a inicializar un estado con una serie de productos random// Los items van a carecer de un idconst [products, setProducts] = React.useState([
    {
      name: "Product 1",
      img: "https://picsum.photos/300",
    },
    {
      name: "Product 2",
      img: "https://picsum.photos/400",
    },
    {
      name: "Product 3",
      img: "https://picsum.photos/350",
    },
  ]);

  // También vamos a tener dos botones// El primero nos ayudará a borrar el primer elemento de la listaconst deleteFirstItem = () => {
    setProducts(products.slice(1));
  };

  // Y el segundo agregará un elemento random al final de la listaconst addItem = () => {
    setProducts([
      ...products,
      {
        name: `Product ${Math.floor(Math.random() * 100) + 5}`,
        img: `https://picsum.photos/${Math.floor(Math.random() * 1000) + 300}`,
      },
    ]);
  };

  // La estructura será la siguiente, por cada elemento// vamos a presentar el componente "<ListItem />"// 👀 Como key de cada elemento vamos a pasar el index del arrayreturn (
    <div><ul>
				{products.map((item, index) => (
          <ListItemitem={item}key={index} />
				))}
      </ul><buttononClick={deleteFirstItem}>
				Delete first item
			</button><buttononClick={addItem}>
				Add random item
			</button></div>
	);
};

Ahora construyamos el componente ListItem:

// ./ListItem.jsx
const ListItem = ({ item }) => {
  // la prop de item tendrá el name y img del product

  // El estado inicial tendrá una descripción vacía para que la actualicemos
  const [description, setDescription] = React.useState("No description");
  // Accedemos al nodo de input mediante useRef()
  const input = React.useRef(null);

  // El botón nos ayudará a guardar la descripción
  // escrita en el input
  const handleClick = () => {
    setDescription(input.current.value);
  };

  // Al final solo le damos estructura
  // y listo
  return (
    <li>
			<img src={item.img} alt="Stock photo" />
			<h2>{item.name}</h2>
			<p>{description}</p>
			<input type="text" ref={input} />
			<button onClick={handleClick}>
				Save description
			</button>
		</li>
	);
};

Con un par de estilos aplicados todo esto junto se verá así:

https://static.platzi.com/media/user_upload/Screenshot%202022-06-13%20at%2021-28-34%20react-keys-b1daa87f-392d-49f1-9a74-7c815fdc3401.jpg

Un carrusel de 5 elementos el cual tiene como función editar las descripciones, el problema empieza cuando queremos agregar una descripción y posteriormente eliminamos el primer elemento como se ve aquí abajo: 👇🏻

https://i.imgur.com/PJyy9gI.gif

El problema de usar el index como key

La descripción de nuestro producto no se encuentra en la misma posición del array, sino en la segunda posición, debido a que el ID siempre es el mismo.

Lo que sucede es que después de eliminar el elemento, el array se actualiza y, por lo tanto, los ID también lo hacen; de esta manera, el ID 2 sigue existiendo, pero en un elemento distinto, lo cual confunde un poco a React, haciendo que adquiera los valores del elemento eliminado. Si en su lugar de usar el index como key ponemos el nombre del producto, pasará lo siguiente: 👇🏻

https://i.imgur.com/3XFlCAK.gif

Puedes ver el proyecto en vivo en este codepen.

Al tener un ID único que no depende de la manipulación del array, los cambios que hagamos sobre cada elemento se aplicarán sobre el elemento que haya causado la interacción.

✅ Lo correcto es que utilices el ID que proviene de la API de la cual obtienes todos esos elementos.

Aprende más acerca de React.js

Esta es solo una fracción de lo que React.js tiene para ofrecer. Te invito a tomar los siguientes cursos para que puedas comprender a fondo cómo funciona esta asombrosa herramienta:

Recuerda que puedes ver la ruta completa en platzi.com/aprendereact.

#NuncaParesDeAprender

Leonardo de los angeles
Leonardo de los angeles
LeoCode0

49094Puntos

hace un año

Todas sus entradas
Escribe tu comentario
+ 2