Skip to content
React

Custom Hooks

Extract reusable logic.

By EZ4Code Team
reacthook

Code

import { useState, useEffect, useCallback } from 'react';

// Data fetching Hook
function useFetch(url) {
    const [data, setData] = useState(null);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState(null);

    const refetch = useCallback(async () => {
        setLoading(true);
        try {
            const res = await fetch(url);
            if (!res.ok) throw new Error('Fetch failed');
            const json = await res.json();
            setData(json);
            setError(null);
        } catch (err) {
            setError(err.message);
        } finally {
            setLoading(false);
        }
    }, [url]);

    useEffect(() => {
        refetch();
    }, [refetch]);

    return { data, loading, error, refetch };
}

// Local storage Hook
function useLocalStorage(key, initial) {
    const [value, setValue] = useState(() => {
        const stored = localStorage.getItem(key);
        return stored ? JSON.parse(stored) : initial;
    });

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

    return [value, setValue];
}

// Debounce Hook
function useDebounce(value, delay) {
    const [debounced, setDebounced] = useState(value);

    useEffect(() => {
        const timer = setTimeout(() => setDebounced(value), delay);
        return () => clearTimeout(timer);
    }, [value, delay]);

    return debounced;
}

// Usage
function Search() {
    const [query, setQuery] = useLocalStorage('query', '');
    const debounced = useDebounce(query, 500);
    const { data } = useFetch(`/api/search?q=${debounced}`);

    return (
        <input value={query} onChange={e => setQuery(e.target.value)} />
    );
}

Explanation

Custom Hooks start with use, extracting state logic for reuse, and can compose other Hooks.

More React Snippets