Hook useReducer
Maneja lógica de estado compleja con actualizaciones predecibles
¿Qué es useReducer?
useReducer es un hook de React que te permite manejar estado con una función reductora. Es una alternativa a useState que es más adecuada para lógica de estado compleja.
Conceptos Clave:
- Estado: El valor de estado actual
- Acción: Un objeto que describe lo que pasó
- Reductor: Una función que toma estado y acción, devuelve nuevo estado
- Dispatch: Función para enviar acciones al reductor
Cuándo Usar useReducer:
- Lógica de estado compleja con múltiples sub-valores
- Las transiciones de estado dependen del estado anterior
- Quieres optimizar el rendimiento para componentes que activan actualizaciones profundas
- Prefieres patrones de gestión de estado estilo Redux
Ejemplo 1: Contador con Historial
Un contador que rastrea el historial y soporta deshacer/rehacer
0
Historial: 1 pasos
Historial: 0
Ejemplo 2: Formulario Complejo
Formulario multi-paso con validación y gestión de estado
Paso 1 de 3
Información Personal
Implementación del Código
'use client'
import { useReducer } from 'react'
type Estado = {
contador: number
historial: number[]
}
type Accion =
| { tipo: 'incrementar' }
| { tipo: 'decrementar' }
| { tipo: 'resetear' }
| { tipo: 'deshacer' }
const estadoInicial: Estado = {
contador: 0,
historial: [0]
}
function reductorContador(estado: Estado, accion: Accion): Estado {
switch (accion.tipo) {
case 'incrementar':
const nuevoContador = estado.contador + 1
return {
contador: nuevoContador,
historial: [...estado.historial, nuevoContador]
}
case 'decrementar':
const contadorDecrementado = estado.contador - 1
return {
contador: contadorDecrementado,
historial: [...estado.historial, contadorDecrementado]
}
case 'resetear':
return estadoInicial
case 'deshacer':
if (estado.historial.length <= 1) return estado
const nuevoHistorial = estado.historial.slice(0, -1)
return {
contador: nuevoHistorial[nuevoHistorial.length - 1],
historial: nuevoHistorial
}
default:
return estado
}
}
export default function Contador() {
const [estado, dispatch] = useReducer(reductorContador, estadoInicial)
return (
<div>
<p>Contador: {estado.contador}</p>
<button onClick={() => dispatch({ tipo: 'incrementar' })}>+</button>
<button onClick={() => dispatch({ tipo: 'decrementar' })}>-</button>
<button onClick={() => dispatch({ tipo: 'resetear' })}>Resetear</button>
<button onClick={() => dispatch({ tipo: 'deshacer' })}>Deshacer</button>
</div>
)
}