DevPath · Aprende a programar ESPTEN

Hooks personalizados y rendimiento

Hooks personalizados: lógica con estado reutilizable

El problema: lógica repetida

Imagina dos componentes que necesitan un interruptor (encendido/apagado). En ambos escribirías lo mismo:

const [abierto, setAbierto] = useState(false);
const alternar = () => setAbierto((v) => !v);

Copiar y pegar esa lógica funciona, pero se desincroniza con el tiempo. La solución de React son los hooks personalizados.

Qué es un hook personalizado

Un hook personalizado es, simplemente, una función cuyo nombre empieza por use y que usa otros hooks por dentro. Encapsula lógica con estado y devuelve lo que el componente necesita:

function useToggle(inicial = false) {
  const [valor, setValor] = useState(inicial);
  const alternar = () => setValor((v) => !v);
  return [valor, alternar];
}

Ahora cualquier componente reutiliza esa lógica sin duplicarla:

function Panel() {
  const [abierto, alternar] = useToggle(false);
  return (
    <div>
      <button onClick={alternar}>Mostrar/ocultar</button>
      {abierto && <p>Contenido visible</p>}
    </div>
  );
}

Lo importante: cada componente que llama a useToggle obtiene su propio estado, aislado. Compartes la lógica, no el estado.

Otro ejemplo: useContador

Un hook puede componer varios hooks y exponer la API que más convenga (un objeto, un array, funciones...):

function useContador(inicial = 0) {
  const [cuenta, setCuenta] = useState(inicial);
  const incrementar = () => setCuenta((c) => c + 1);
  const reiniciar = () => setCuenta(inicial);
  return { cuenta, incrementar, reiniciar };
}

Las reglas de los hooks

Para que React pueda asociar cada llamada con su estado, los hooks tienen dos reglas inquebrantables:

  1. Llámalos solo en el nivel superior. Nunca dentro de if, bucles, condicionales o funciones anidadas. El orden de las llamadas debe ser el mismo en cada render.
  2. Llámalos solo desde componentes de React o desde otros hooks personalizados. No desde funciones JavaScript normales.
// ❌ MAL: hook dentro de un if (el orden cambia entre renders)
if (activo) {
  const [x, setX] = useState(0);
}

// ✅ BIEN: en el nivel superior; la condición va dentro
const [x, setX] = useState(0);
if (activo) { /* usa x */ }

Un hook personalizado es solo una convención de nombre (use...) más estas reglas. No hay "magia": es una función que organiza tus hooks.

Ejemplos

Un hook useToggle reutilizable

function useToggle(inicial) {
  const [valor, setValor] = React.useState(inicial);
  const alternar = () => setValor((v) => !v);
  return [valor, alternar];
}
// Simulación: dos "instancias" tienen estado independiente
let estado1 = false, estado2 = true;
console.log("inicio:", estado1, estado2);
Pon esto en práctica

DevPath es un curso práctico: aquí lees la teoría; en la app la pones en práctica con ejercicios que se ejecutan de verdad, sin conexión.

Empezar gratis en la app →
Rendimiento: por qué re-renderiza React →