Como funciona el hook useState y como usarlos con Arrays y Objetos

  Diego Artiles   •     7 Min

En este artículo te voy a explicar que es y para que sirve el hook useState de React, además de los distintos usos que le podemos dar.

¿Qué son los hooks de React?

Los hooks son funciones que se "atan" o "enganchan" a los componente de tipo función (componentes funcionales) y nos aportan muchas de las características que teníamos en las componentes de tipo clase.

Estas funciones se introdujeron en la versión 16.8 de React, por ende, antes de utilizarlos asegúrate de tener esta versión o posterior.

Para que sirve el hook useState

El hook useState sirve para almacenar un estado a través de una variable en nuestro componente.

¿Cómo se usa el useState?

Como les había comentado, los hooks son funciones los cuales reciben un parámetro que representa el valor por defecto que tendrá nuestro estado y retorna un arreglo de dos elementos, el primer elemento contiene el estado actual y el segundo una función para modificar dicho estado.

import React, { useState } from "react"; // Importamos useState desde 'react'

const App = () => {
  const state = useState("default value"); // Valor inicial del estado
  const stateValue = state[0]; // El primer elemento es el valor del estado
  const setStateValue = state[1]; // El segundo elemento es la función que utilizaremos para actualizar el estado

  // A continuación mostramos el valor del estado y lo cambiamos a 'Another value' al hacer clic en el elemento div
  return <div onClick={() => setStateValue('Another value')}>{stateValue}</div>;
};

export default App;
Manera larga de declarar estos estados

Si bien es cierto, no es la mejor forma de declarar el estado y su actualizador en variables separadas, si que es más fácil de entender 👨‍💻

Pero la forma que se suele utilizar y la más corta para declararlas, es la siguiente:

const [stateValue, setStateValue] = useState("default value");

Con la línea anterior obtenemos el mismo resultado, pero utilizando menos líneas de código. Si acostumbras a trabajar con el menor código posible esta forma te gustará 😁

En este caso yo inicialice el estado con un string pero podemos usar cualquier tipo de valor como por ejemplo:

  • Arreglos
  • Objetos
  • Booleanos
  • Strings

Y en este artículo te mostraré ejemplos con Arreglos y Objetos 😜

Usar Arreglos o Arrays en useState

Aquí hay una particularidad con este tipo de datos y el hook useState que ya les iré contando.

Primero declaramos nuestros useState con Arreglos, en este caso yo usaré el ejemplo de un array que contenga nombre de frutas:

const [fruits, setFruits] = useState(['Banana', 'Fresa', 'Durazno']);
Declarando el estado

Si quisiéramos agregar el nombre de otra fruta a esta lista, seguramente estés pensando en usar el método push(), pero lamentablemente no nos servirá y antes de explicarte porque, te muestro como haríamos ese cambio de estado:

  fruits.push('Manzana') // Opción 1
  setFruits(fruits.push('Manzana')) // Opción 2
Intentando agregar una fruta a nuestra lista usando el método push del array

Si intentaste esto alguna vez seguramente te diste cuenta que no funcionó del todo bien, y esto es debido a las siguientes razones:

  • La variable fruits es inmutable (no se puede modificar), por eso tiene su función "actualizadora" (Opción 1)
  • Utilizar el método push dentro de la función setFruits tampoco funciona, porque si repasamos la teoría nos daremos cuenta que este método a pesar de agregar un nuevo elemento a un array lo que retorna es el length del array resultante y esto es lo que estaría recibiendo setFruits, que en nuestro caso es 4, es por eso que el nuevo valor de nuestro estado es 4 (Opción 2).

Formas de actualizar un array en useState

Antes de explicar cual es la manera correcta de modificar el valor de este elemento, tenemos que saber que la función actualizadora (setFruits en nuestro caso) puede recibir una función que tiene como único parámetro el valor actual del estado y retornar el nuevo valor del mismo. Seguramente al momento de leer esto se te venga a la cabeza como actualizar nuestro estado 😀, veamos si coincidimos:

Usando el método concat(), podemos actualizar nuestro estado según las dos formas aprendidas: usando la función interna de la función actualizadora o pasando directamente el valor nuevo a la función actualizadora.

Dejo a continuación un ejemplo con ambas opciones:

setFruits(currentFruits => currentFruits.concat('Manzana')) // Opción 1
setFruits(fruits.concat('Manzana')) // Opción 2

// Ambas opciones son validas
Actualizando nuestra lista de fruta con el método concat()

La función interna de setFruits puede ser útil cuando queramos desarrollar cierta lógica antes de definir el nuevo valor, pero particularmente no lo suelo hacer, primero preparo el valor nuevo en una variable y se lo paso a setFruits para actualizar el estado.

React no actualiza el estado de manera instantánea, sino que agrega el pedido de actualización a la cola para el próximo renderizado del componente, y la siguiente que vez que pase por nuestro useState omitirá el valor por defecto que le asignamos y en su lugar usará el valor que estaba en la cola.

Ya que sabemos la manera correcta de actualizar el estado, hay otra forma de hacerlo mucho más amigable y corta, usando spread operator

setFruits([...fruits, 'Manzana'])

Usar objetos en useState

Con lo aprendido anteriormente, usemos estos mismos conocimiento con este tipo de dato, primero veamos cual es nuestro candidato para esta prueba 😄

  const [person, setPerson] = useState(
    {
      name: 'Diego',
      age: 22,
    }
  );
Definiendo el estado

Como bien lo dice el título ahora probaremos con objetos, en este caso son los datos de una persona que se llama "Diego" como yo y casualmente tiene mi misma edad 🤔 jaja.

¡Concentrémonos! Supongamos que me quiero aumentar la edad a 30, ya sabemos que para editar la propiedad de un objeto hacemos lo siguiente:

person.age = 30

Por ende podemos pensar que para actualizar el valor de nuestro estado haríamos esto

person.age = 30
setPerson(person)

pero no nos funciona porque para React el estado nunca cambió por ende no vio la necesidad de renderizar el componente nuevamente para reflejar este "cambio".

Uno de los requisitos para que React refleje un nuevo estado, es que el mismo cambie y en el caso de los objetos utiliza Object.is para hacer esta comprobación

Cuando tengamos que actualizar una propiedad de un objeto debemos pasarle uno nuevo junto a la propiedad modificada, para esto podemos usar el spread operator, te dejo un ejemplo 😆

import React, { useState } from "react";

const Person = () => {
  const [person, setPerson] = useState(
    {
      name: 'Diego',
      age: 22,
    }
  );
  const changeAge = () => {
    setPerson({...person, age: 30})
  }


  return <div onClick={() => changeAge()}>Edad de la persona {person.age}</div>;
};

export default Person;
Actualizamos mi edad cuando demos clic a el elemento div

Agradecimientos

Mil gracias si llegaste hasta aquí, si te sirvió de algo este artículo déjamelo saber en los comentarios y compártelo con tus amigos 🥰

Si te quedaron dudas o deseas que explique algún otro hook o cosa del mundo del frontend, avísame desde los comentarios 🤩