Custom Hooks
Un custom hook es simplemente una función de JavaScript que empieza con "use" y puede llamar otros hooks de React. Son la forma de extraer y reutilizar lógica que involucra estado o efectos. Piénsalos como crear tus propias herramientas personalizadas: igual que React te da useState y useEffect listos para usar, tú puedes crear useFetch, useLocalStorage, useDebounce, useWindowSize. Cualquier lógica que repites en múltiples componentes es candidata perfecta para convertirse en un custom hook.
Un punto clave: los custom hooks no comparten estado entre componentes. Cada componente que llama useFetch("/api/users") obtiene su propia copia del estado (sus propios datos, su propio cargando, su propio error). Lo que se comparte es la lógica, no los datos. Si necesitas estado compartido, necesitas Context o una librería de estado global.
La regla del nombre: si la función usa hooks, debe empezar con "use" (React lo verifica). Si no usa hooks, es una función normal.
// Hook para fetch de datos
function useFetch(url) {
const [datos, setDatos] = useState(null);
const [cargando, setCargando] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const controller = new AbortController();
const cargar = async () => {
setCargando(true);
try {
const resp = await fetch(url, { signal: controller.signal });
if (!resp.ok) throw new Error(resp.statusText);
setDatos(await resp.json());
} catch (err) {
if (err.name !== "AbortError") setError(err.message);
} finally {
setCargando(false);
}
};
cargar();
return () => controller.abort(); // Cleanup
}, [url]);
return { datos, cargando, error };
}
// Hook para LocalStorage
function useLocalStorage(clave, valorInicial) {
const [valor, setValor] = useState(() => {
const guardado = localStorage.getItem(clave);
return guardado ? JSON.parse(guardado) : valorInicial;
});
const guardar = useCallback((nuevoValor) => {
setValor(nuevoValor);
localStorage.setItem(clave, JSON.stringify(nuevoValor));
}, [clave]);
return [valor, guardar];
}
// Uso de los custom hooks
function App() {
const { datos, cargando } = useFetch("https://api.example.com/users");
const [usuario, setUsuario] = useLocalStorage("usuario", null);
if (cargando) return <p>Cargando...</p>;
return <div>{datos?.map(u => <p key={u.id}>{u.name}</p>)}</div>;
}
Practica esta lección
Resuelve los ejercicios del curso de React en la app, gratis y con corrección automática.
Empezar a practicar