useState es un Hook de React que te permite agregar una variable de estado a tu componente.

const [state, setState] = useState(initialState)

Referencia

useState(initialState)

Llama a useState en el nivel superior de tu componente para declarar una variable de estado.

import { useState } from 'react';

function MyComponent() {
const [age, setAge] = useState(28);
const [name, setName] = useState('Taylor');
const [todos, setTodos] = useState(() => createTodos());
// ...

La convención es nombrar variables de estado como [algo, setAlgo] usando desestructuración de arrays.

Ver más ejemplos abajo.

Parámetros

  • initialState: El valor que deseas que tenga el estado inicialmente. Puede ser un valor de cualquier tipo, pero hay un comportamiento especial para las funciones. Este argumento se ignora después del renderizado inicial.
    • Si pasa una función como initialState, se tratará como una función inicializadora. Debe ser pura, no debe aceptar argumentos y debe devolver un valor de cualquier tipo. React llamará a tu función de inicialización al inicializar el componente y almacenará su valor de devolución como el estado inicial. Ve un ejemplo debajo.

Devuelve

useState devuelve un array con exactamente dos valores:

  1. El estado actual. Durante el primer renderizado, coincidirá con el initialState que hayas pasado.
  2. La función set que te permite actualizar el estado a un valor diferente y desencadenar un nuevo renderizado.

Advertencias

  • useState es un Hook, por lo que solo puedes llamarlo en el nivel superior de tu componente o en tus propios Hooks. No puedes llamarlo dentro de bucles o condiciones. Si lo necesitas, extrae un nuevo componente y mueva el estado a él.
  • En Modo estricto, React llamará a tu función de inicialización dos veces para ayudarte a encontrar impurezas accidentales. Este es un comportamiento exclusivo de desarrollo y no ocurre en producción. Si tu función de inicialización es pura (como debería ser), esto no debería afectar la lógica de tu componente. Se ignorará el resultado de una de las llamadas.

Funciones set , como setAlgo(siguienteEstado)

La función set devuelta por useState te permite actualizar el estado a un valor diferente y desencadenar un nuevo renderizado. Puedes pasar el siguiente estado directamente, o una función que lo calcule a partir del estado anterior:

const [name, setName] = useState('Edward');

function handleClick() {
setName('Taylor');
setAge(a => a + 1);
// ...

Parámetros

  • siguienteEstado: El valor que deseas que tenga el estado. Puede ser un valor de cualquier tipo, pero hay un comportamiento especial para las funciones.
  • Si pasas una función como siguienteEstado, se tratará como una función de actualización. Debe ser pura, debe tomar el estado pendiente como único argumento y debe devolver el siguiente estado. React pondrá tu función de actualización en una cola y volverá a renderizar tu componente. Durante el próximo renderizado, React calculará el siguiente estado aplicando todas las actualizaciones en cola al estado anterior. Ve un ejemplo debajo.

Devuelve

Las funciones set no tienen un valor de devolución.

Advertencias

  • La función set solo actualiza la variable de estado para el próximo renderizado. Si lees la variable de estado después de llamar a la función set, seguirás obteniendo el valor anterior que estaba en la pantalla antes de tu llamada.

  • Si el nuevo valor que proporcionas es idéntico al estado actual, según lo determinado por un Object.is, React omitirá volver a renderizar el componente y sus hijos. Esta es una optimización. Aunque en algunos casos React aún puede necesitar llamar a tu componente antes de omitir los hijos, no debería afectar tu código.

  • React agrupa actualizaciones de estado. Actualiza la pantalla después de que todos los controladores de eventos se hayan ejecutado y hayan llamado a sus funciones set. Esto evita múltiples renderizados durante un solo evento. En el raro caso de que necesite forzar a React a actualizar la pantalla antes, por ejemplo, para acceder al DOM, puedes usar flushSync.

  • La función set tiene una identidad estable, por lo que a menudo verás que se omite de las dependencias de los Efectos, pero que se incluya no causa que el Efecto se dispare. Si el linter te permite omitir una dependencia sin errores, es seguro hacerlo. Aprende más sobre eliminar dependencias de los Efectos.

  • Llamar a la función set durante el renderizado solo está permitido desde el componente que se está renderizando. React descartará su salida e inmediatamente intentará renderizarlo nuevamente con el nuevo estado. Este patrón rara vez se necesita, pero puedes usarlo para almacenar información de los renderizados anteriores. Ve un ejemplo debajo.

  • En Modo estricto, React llamará a tu función de actualización dos veces para ayudarte a encontrar impurezas accidentales. Este es un comportamiento exclusivo de desarrollo y no ocurre en producción. Si tu función de actualización es pura (como debería ser), esto no debería afectar la lógica de tu componente. Se ignorará el resultado de una de las llamadas.


Uso

Agregar estado a un componente

Llama a useState en el nivel superior de tu componente para declarar una o más variables de estado.

import { useState } from 'react';

function MyComponent() {
const [age, setAge] = useState(42);
const [name, setName] = useState('Taylor');
// ...

La convención es nombrar variables de estado como [algo, setAlgo] utilizando la desestructuración de arrays.

useState devuelve un array con exactamente dos elementos:

  1. El estado actual de esta variable de estado, establecida inicialmente en el estado inicial que proporcionaste.
  2. La función set que te permite cambiarlo a cualquier otro valor en respuesta a la interacción.

Para actualizar lo que está en la pantalla, llama a la función set con algún estado:

function handleClick() {
setName('Robin');
}

React almacenará el siguiente estado, renderizará tu componente nuevamente con los nuevos valores y actualizará la interfaz de usuario.

Atención

Llamar a la función set no cambia el estado actual en el código que ya se está ejecutando :

function handleClick() {
setName('Robin');
console.log(name); // ¡Sigue siendo "Taylor"!
}

Solo afecta lo que useState devolverá a partir del siguiente renderizado.

Prueba algunos ejemplos

Ejemplo 1 de 4:
Contador (número)

En este ejemplo, la variable contador contiene un número. Al hacer click en el botón lo incrementa

import { useState } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <button onClick={handleClick}>
      Hiciste clic {count} veces
    </button>
  );
}


Actualización de estado con base en el estado anterior

Supongamos que age es 42. La función handler llama setAge(age + 1) tres veces:

function handleClick() {
setAge(age + 1); // setAge(42 + 1)
setAge(age + 1); // setAge(42 + 1)
setAge(age + 1); // setAge(42 + 1)
}

¡Sin embargo, después de un click, age solo será 43 en lugar de 45! Esto se debe a que llamar a la función set no actualizará la variable de estado age en el código que ya se está ejecutando. Así que cada llamada setAge(age + 1) se convierte en setAge(43).

Para resolver este problema, puedes pasar una función de actualización a setAge en lugar del siguiente estado:

function handleClick() {
setAge(a => a + 1); // setAge(42 => 43)
setAge(a => a + 1); // setAge(43 => 44)
setAge(a => a + 1); // setAge(44 => 45)
}

Aquí, a => a + 1 es la función de actualización. Toma el estado pendiente y calcula el siguiente estado a partir de él.

React pone sus funciones de actualización en una cola. Entonces, durante el siguiente renderizado, las llamará en el mismo orden:

  1. a => a + 1 recibirá 42 como estado pendiente y devolverá 43 como el siguiente estado.
  2. a => a + 1 recibirá 43 como estado pendiente y devolverá 44 como el siguiente estado.
  3. a => a + 1 recibirá 44 como estado pendiente y devolverá 45 como el siguiente estado.

No hay otras actualizaciones en cola, por lo que React almacenará 45 como el estado actual al final.

Por convención, es común nombrar el argumento de estado pendiente como la primera letra del nombre de la variable de estado, como a para age. No obstante, también puedes llamarlo como prevAge o cualquier otra cosa que te resulte más clara.

React puede llamar a tus actualizadores dos veces en desarrollo para verificar que sean puros.

Profundizar

¿Siempre se prefiere usar un actualizador?

Es posible que escuches una recomendación para escribir siempre código como setEdad(e => e + 1) si el estado que está configurando se calcula a partir del estado anterior. No hay daño en ello, pero tampoco es necesario siempre.

En la mayoría de los casos, no hay diferencia entre estos dos enfoques. React siempre se asegura de que para las acciones intencionales del usuario, como los clicks, la variable de estado edad se actualizará antes del siguiente click. Esto significa que no hay riesgo de que un controlador de clicks vea un mensaje “obsoleto” de edad al comienzo del controlador de evento.

Sin embargo, si realizas varias actualizaciones dentro del mismo evento, los actualizadores pueden ser útiles. También son útiles si acceder a la variable de estado en sí es un inconveniente (es posible que te encuentres con esto al optimizar los renderizados).

Si prefieres la coherencia a una sintaxis un poco más detallada, es razonable escribir siempre un actualizador si el estado que está configurando se calcula a partir del estado anterior. Si se calcula a partir del estado anterior de alguna otra variable de estado, es posible que desees combinarlos en un solo objeto y uses un reducer.

Prueba algunos ejemplos

Ejemplo 1 de 2:
Pasar la función de actualización

Este ejemplo pasa la función de actualización, por lo que funciona el botón “+3”.

import { useState } from 'react';

export default function Counter() {
  const [age, setAge] = useState(42);

  function increment() {
    setAge(a => a + 1);
  }

  return (
    <>
      <h1>Tu edad: {age}</h1>
      <button onClick={() => {
        increment();
        increment();
        increment();
      }}>+3</button>
      <button onClick={() => {
        increment();
      }}>+1</button>
    </>
  );
}


Actualización de objetos y arrays en el estado

Se pueden poner objetos y arrays en el estado. En React, el estado se considera de solo lectura, por lo que debes reemplazar en lugar de mutar tus objetos existentes. Por ejemplo, si tienes un objeto formulario en el estado, no lo actualices así:

// 🚩 No cambies un objeto en un estado como este:
formulario.primerNombre = 'Taylor';

En su lugar, reemplaza todo el objeto creando uno nuevo:

// ✅ Reemplaza el estado con un nuevo objeto
setForm({
...form,
firstName: 'Taylor'
});

Lee actualizar objetos en el estado y actualizar arrays en el estado para saber más.

Prueba algunos ejemplos

Ejemplo 1 de 4:
Formulario (objeto)