DEV Community

Md Yusuf
Md Yusuf

Posted on

Custom Hooks in React

Custom Hooks in React are a powerful feature that allow you to extract and reuse logic across multiple components. They enable you to encapsulate complex stateful logic, making your components cleaner and easier to maintain. Here’s a quick overview and example of how to create and use custom hooks.

Creating a Custom Hook

A custom hook is essentially a JavaScript function whose name starts with use and that may call other hooks inside it. Here’s a simple example of a custom hook that manages a counter:

import { useState } from 'react';

// Custom Hook: useCounter
function useCounter(initialValue = 0) {
    const [count, setCount] = useState(initialValue);

    const increment = () => setCount(c => c + 1);
    const decrement = () => setCount(c => c - 1);
    const reset = () => setCount(initialValue);

    return { count, increment, decrement, reset };
}

export default useCounter;
Enter fullscreen mode Exit fullscreen mode

Using the Custom Hook

You can use the useCounter hook in any functional component:

import React from 'react';
import useCounter from './useCounter';

function CounterComponent() {
    const { count, increment, decrement, reset } = useCounter(0);

    return (
        <div>
            <h1>Count: {count}</h1>
            <button onClick={increment}>Increment</button>
            <button onClick={decrement}>Decrement</button>
            <button onClick={reset}>Reset</button>
        </div>
    );
}

export default CounterComponent;
Enter fullscreen mode Exit fullscreen mode

Key Points

  1. Naming Convention: Always start the custom hook's name with use to follow React's convention.
  2. Reusability: Custom hooks can be reused across multiple components, promoting DRY (Don't Repeat Yourself) code.
  3. State Management: You can manage state, perform side effects, and leverage other hooks within a custom hook.

Advanced Example: Fetching Data

Here’s a more advanced custom hook for fetching data:

import { useState, useEffect } from 'react';

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

    useEffect(() => {
        const fetchData = async () => {
            try {
                const response = await fetch(url);
                if (!response.ok) throw new Error('Network response was not ok');
                const result = await response.json();
                setData(result);
            } catch (error) {
                setError(error);
            } finally {
                setLoading(false);
            }
        };

        fetchData();
    }, [url]);

    return { data, loading, error };
}

export default useFetch;
Enter fullscreen mode Exit fullscreen mode

Usage

You can use the useFetch hook in a component to fetch data:

import React from 'react';
import useFetch from './useFetch';

function DataFetchingComponent() {
    const { data, loading, error } = useFetch('https://api.example.com/data');

    if (loading) return <p>Loading...</p>;
    if (error) return <p>Error: {error.message}</p>;

    return (
        <div>
            <h1>Data:</h1>
            <pre>{JSON.stringify(data, null, 2)}</pre>
        </div>
    );
}

export default DataFetchingComponent;
Enter fullscreen mode Exit fullscreen mode

Custom hooks are a great way to encapsulate logic and share functionality across your components in a clean and maintainable way.

Top comments (0)