Saltar al contenido
Curso de React
Todos los cursos Ir al ejercicio →

Más hooks: useRef, useReducer y hooks propios

  • ⏱ 55 minutos
  • 📶 Nivel: principiante
  • 🧩 Incluye ejercicio

💡 🎯 Al terminar esta lección podrás…

  • Acceder al DOM y guardar valores mutables con useRef.
  • Organizar estados complejos con useReducer.
  • Saber cuándo (y cuándo no) memorizar.
  • Crear y reutilizar hooks personalizados.

1.useRef: una referencia que no provoca dibujos

useRef devuelve un objeto que se conserva entre dibujos y cuya propiedad .current puedes leer y cambiar sin que React vuelva a dibujar. Tiene dos usos principales:

UsoEjemplo
Acceder a un elemento del DOMEnfocar un campo, hacer scroll, medir un tamaño, reproducir un video
Guardar un valor mutable que no se muestraEl id de un temporizador, el valor anterior de algo, un contador interno
⚛️ Enfocar un campo con una referencia
Consola
⚛️ Guardar un valor sin redibujar
Consola

⚠️ Importante · Estado frente a referencia

Si el valor se muestra en pantalla, debe ser estado. Si solo lo necesitas «recordar» sin dibujarlo, usa una referencia. No leas ni escribas ref.current mientras dibujas (en el cuerpo del componente): hazlo en eventos y efectos.

2.useReducer: estado con muchas acciones

Cuando un estado tiene muchas formas de cambiar (agregar, quitar, editar, vaciar…), repartir setX por todo el componente se desordena. useReducer concentra toda la lógica en una sola función, el reductor, que recibe el estado actual y una acción y devuelve el estado nuevo.

⚛️ Un contador con acciones
Consola
useStateuseReducer
Estados simples (un número, un texto, un booleano)Estados complejos (objetos con varias partes o listas con muchas operaciones)
Pocas formas de cambiarMuchas acciones relacionadas
La lógica está en los manejadores de eventosLa lógica está centralizada y es fácil de probar

💡 Consejo · Reductor + Context

La combinación useReducer + Context es la «mini Redux» que muchas aplicaciones medianas necesitan. La verás completa en el proyecto final.

3.useMemo y useCallback: optimizar con cabeza

React es rápido por defecto. Solo cuando midas un problema de rendimiento te servirán estas dos herramientas, que recuerdan un resultado entre dibujos:

HookRecuerda…Se recalcula cuando…
useMemo(() => cálculo, [deps])El resultado de un cálculo costosocambia alguna dependencia
useCallback(fn, [deps])La función misma (misma referencia)cambia alguna dependencia
⚛️ useMemo: no repetir un cálculo pesado
Consola

⚠️ Importante · No los uses «por si acaso»

Memorizar tiene un costo (memoria y código más difícil de leer). Empieza sin ellos, mide con las herramientas de desarrollo y úsalos donde de verdad haya lentitud. useCallback solo aporta algo cuando pasas la función a un componente envuelto en memo o a las dependencias de un efecto.

4.Hooks personalizados: reutilizar lógica

Un hook personalizado es una función cuyo nombre empieza por use y que usa otros hooks dentro. Sirve para extraer lógica con estado y reutilizarla en varios componentes, igual que un componente reutiliza JSX.

⚛️ useToggle y useContador
Consola

📌 Nota · Se comparte la lógica, no el estado

Cada vez que usas un hook personalizado, cada componente obtiene su propio estado. Los dos <Votos /> tienen contadores separados aunque usen el mismo hook.

Un clásico: useLocalStorage
function useLocalStorage(clave, inicial) {
  const [valor, setValor] = useState(() => {
    const guardado = localStorage.getItem(clave);
    return guardado !== null ? JSON.parse(guardado) : inicial;
  });

  useEffect(() => {
    localStorage.setItem(clave, JSON.stringify(valor));
  }, [clave, valor]);

  return [valor, setValor];
}

// Se usa igual que useState, pero persiste
const [nombre, setNombre] = useLocalStorage("nombre", "");

5.Las reglas de los hooks

💡 Consejo · Instala el linter

Los proyectos de Vite traen eslint-plugin-react-hooks, que te avisa si rompes estas reglas o si olvidas una dependencia. Es de las ayudas más valiosas al aprender.

6.Errores frecuentes

📒 Apuntes para llevar

  • useRef guarda un valor mutable que no redibuja y da acceso a elementos del DOM (ref={campo} → campo.current).
  • Si se muestra en pantalla, es estado; si solo se recuerda, es ref.
  • useReducer(reductor, inicial) centraliza los cambios de un estado complejo con acciones (dispatch({ tipo })).
  • El reductor es una función pura: (estado, acción) → estado nuevo.
  • useMemo recuerda un resultado; useCallback recuerda una función. Úsalos solo si mides un problema.
  • Un hook personalizado (useAlgo) extrae lógica con estado para reutilizarla.
  • Reglas de los hooks: nivel superior y solo en componentes u otros hooks.

7.Glosario

TérminoSignificado
useRefHook que devuelve un objeto { current } estable entre dibujos.
useReducerHook para manejar estado complejo mediante un reductor y acciones.
Reductor (reducer)Función pura que recibe estado y acción y devuelve el nuevo estado.
AcciónObjeto que describe qué ocurrió, por ejemplo { tipo: "sumar" }.
useMemoHook que recuerda el resultado de un cálculo mientras no cambien sus dependencias.
useCallbackHook que recuerda una función con la misma referencia entre dibujos.
Hook personalizadoFunción useAlgo que reutiliza lógica con hooks entre componentes.

🧠 Comprueba lo aprendido

Elige una respuesta en cada pregunta. Verás al instante si acertaste y por qué.

¿Qué ocurre al cambiar miRef.current?

Necesitas enfocar un <input> al pulsar un botón. ¿Qué usas?

¿Qué debe devolver un reductor?

¿Cuál es un nombre válido para un hook personalizado?

¿Cuándo conviene usar useMemo?

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.

Ir al ejercicio