Custom hooks
A custom hook is just a function whose name starts with use. That naming convention tells React it can call other hooks inside it. The pattern is how you extract repeated data-fetching, form, or state logic into a reusable piece that any component can call.
import { useEffect, useState } from 'react';
interface Book {
id: number;
title: string;
author: string;
}
export function useBooks() {
const [books, setBooks] = useState<Book[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
const controller = new AbortController();
fetch('/api/books', { signal: controller.signal })
.then((res) => {
if (!res.ok) throw new Error('HTTP ' + res.status);
return res.json();
})
.then(setBooks)
.catch((err) => {
if (err.name !== 'AbortError') setError(err.message);
})
.finally(() => setLoading(false));
return () => controller.abort();
}, []);
return { books, loading, error };
}A custom hook that wraps the fetch-and-state pattern.
import { useBooks } from './useBooks';
export function BookList() {
const { books, loading, error } = useBooks();
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error}</p>;
return books.map((b) => <BookCard key={b.id} book={b} />);
}Any component can now get books, loading, and error in one line.
Quiz: Quiz
Loading practiceโฆ