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 馃ぉ