Estado con useState
💡 🎯 Al terminar esta lección podrás…
- Guardar y actualizar datos con
useState. - Responder a eventos pasando funciones.
- Actualizar objetos y arrays sin mutarlos.
- Usar la forma funcional cuando el valor nuevo depende del anterior.
1.Por qué una variable normal no basta
Hasta ahora tus componentes mostraban datos fijos. Para que una interfaz reaccione (un contador, un menú que se abre, un campo que se escribe) el componente necesita recordar un valor y volver a dibujarse cuando ese valor cambie.
Prueba con una variable normal. Pulsa el botón: el valor sí cambia en memoria (míralo en la consola), pero la pantalla no se actualiza:
| Problema | Por qué ocurre |
|---|---|
| La pantalla no cambia | React solo vuelve a dibujar un componente cuando él lo decide; cambiar una variable local no se lo avisa. |
| El valor se pierde | Cada vez que el componente se dibuja, la función se ejecuta de nuevo y let cuenta = 0 empieza desde cero. |
Necesitamos algo que (1) conserve el valor entre dibujos y (2) avise a React de que debe volver a dibujar. Eso es el estado.
2.useState: tu primera herramienta de estado
useState es un hook: una función especial de React (siempre empieza por use) que añade memoria a un componente. Devuelve un par: el valor actual y una función para cambiarlo.
setCuenta y React vuelve a dibujar el número. «Reiniciar» lo devuelve a 0.- Declaras el estado con
useState(valorInicial). - Lo lees como una variable normal:
{cuenta}. - Lo cambias solo con el setter:
setCuenta(nuevoValor). React guarda el valor nuevo y vuelve a dibujar el componente.
⚠️ Importante · Nunca modifiques el estado directamente
Escribir cuenta = cuenta + 1 o cuenta++ no funciona: React no se entera. Usa siempre el setter (setCuenta). Por eso en el ejemplo se declara con const: no se reasigna jamás.
3.Eventos: responder a lo que hace la persona
Para reaccionar a clics, teclas o cambios usas atributos de evento en camelCase y les pasas una función (no el resultado de llamarla).
| Evento | Atributo en React | Cuándo se dispara |
|---|---|---|
| Clic | onClick | Al pulsar un elemento |
| Cambio de un campo | onChange | Cada vez que cambia el valor de un <input> |
| Envío de formulario | onSubmit | Al enviar un <form> |
| Tecla pulsada | onKeyDown | Al pulsar una tecla |
| Ratón encima | onMouseEnter | Al entrar el puntero |
⚠️ Importante · El error más común con eventos
Escribir onClick={saludar()} llama a la función al dibujar, no al hacer clic. Debes pasar la función: onClick={saludar} o onClick={() => saludar()}. Con el setter pasa igual: onClick={setCuenta(1)} provocaría un bucle infinito.
4.Actualizar con seguridad: la forma funcional
Cuando el valor nuevo depende del anterior, pásale al setter una función que recibe el valor previo. Es la forma segura, sobre todo si hay varias actualizaciones seguidas:
El primer botón solo suma 1, porque las tres llamadas leen el mismo valor de a. El segundo suma 3, porque cada función recibe el resultado de la anterior.
📌 Nota · El estado es una «foto»
En cada dibujo, el valor del estado es fijo, como una fotografía. Llamar al setter no cambia la variable de ese dibujo: pide a React otro dibujo con el valor nuevo. Por eso console.log(cuenta) justo después de setCuenta(cuenta + 1) aún muestra el valor viejo.
5.Estado con textos, booleanos, objetos y arrays
El estado puede guardar cualquier valor. Con objetos y arrays hay una regla de oro: nunca los mutes; crea una copia nueva (con *spread* o con map/filter) y pásala al setter.
| Quiero… | Hazlo así (sin mutar) |
|---|---|
| Cambiar una propiedad de un objeto | setUsuario({ ...usuario, puntos: 5 }) |
| Añadir a un array | setLista([...lista, nuevo]) |
| Quitar de un array | setLista(lista.filter(x => x.id !== id)) |
| Cambiar un elemento de un array | setLista(lista.map(x => x.id === id ? { ...x, hecho: true } : x)) |
| Evita | usuario.puntos = 5, lista.push(nuevo), lista.sort() (mutan) |
6.Cada componente tiene su propio estado
El estado pertenece a cada copia del componente. Si usas <Contador /> dos veces, cada una guarda su propio valor y no se mezclan:
💡 Consejo · Reglas de los hooks
Los hooks solo se llaman en el nivel superior de un componente (nunca dentro de if, bucles o funciones anidadas) y solo en componentes o en otros hooks. Así React siempre los ve en el mismo orden.
7.Errores frecuentes
- Modificar el estado directamente (
cuenta++,lista.push(x)): la pantalla no se actualiza. - Llamar a la función en lugar de pasarla:
onClick={sumar()}vs.onClick={sumar}. - Mutar objetos y arrays en lugar de crear copias nuevas.
- Esperar el valor nuevo justo después del setter: el estado es una foto; el valor nuevo llega en el siguiente dibujo.
- Guardar en estado algo que se puede calcular de otros datos (por ejemplo, el total): cálculalo en cada dibujo.
- Llamar a
useStatedentro de unifo un bucle: rompe el orden de los hooks. - Olvidar el valor inicial:
useState()empieza enundefined; inicializa siempre con un valor del tipo correcto.
📒 Apuntes para llevar
- El estado es la memoria de un componente; cuando cambia, React vuelve a dibujar el componente.
const [valor, setValor] = useState(inicial)devuelve el valor actual y su setter.- Cambia el estado solo con el setter, nunca asignando directamente.
- Para eventos pasa una función:
onClick={sumar}oonClick={() => …}; no la llames. - Si el nuevo valor depende del anterior usa la forma funcional:
setN(n => n + 1). - Con objetos y arrays crea copias (
...,map,filter) en vez de mutar. - Cada copia de un componente tiene su propio estado.
- Los hooks se llaman siempre en el nivel superior del componente.
8.Glosario
| Término | Significado |
|---|---|
| Estado | Datos que un componente recuerda y que, al cambiar, provocan un nuevo dibujo. |
| Hook | Función de React que empieza por use y añade capacidades a un componente. |
| Setter | Función que devuelve useState para cambiar el valor y pedir un nuevo dibujo. |
| Evento | Algo que ocurre en la interfaz (un clic, una tecla) y al que puedes responder. |
| Inmutabilidad | Práctica de no modificar los datos existentes y crear copias nuevas. |
| Dibujar (render) | Ejecutar el componente para calcular qué debe mostrarse. |
Spread ... | Sintaxis para copiar propiedades o elementos al crear un objeto o array nuevo. |
🧠 Comprueba lo aprendido
Elige una respuesta en cada pregunta. Verás al instante si acertaste y por qué.
¿Qué devuelve useState(0)?
Devuelve un par: [valor, setValor], que normalmente se desestructura.
¿Por qué cuenta++ no actualiza la pantalla?
Solo el setter avisa a React de que debe volver a dibujar.
¿Cuál es la forma correcta de pasar el manejador de clic?
sumar() ejecutaría la función al dibujar; hay que pasar la función misma.
¿Cómo añades un elemento a un array guardado en estado?
Se crea un array nuevo con una copia más el elemento, y se pasa al setter.
Tres llamadas seguidas setN(n + 1) con n valiendo 0, ¿cuánto vale n en el siguiente dibujo?
Las tres leen el mismo valor (0) de esa «foto». Con setN(n => n + 1) sumarían 3.
Tu progreso se guarda en este navegador y se refleja en el índice del curso.
💡 🚀 ¡Ahora te toca!
La práctica fija lo aprendido. Pasa al ejercicio de esta lección.