R

React Handbook

Clean • Professional

React Custom Hooks – Creating Reusable Logic

2 minute

React Custom Hooks

In React, Hooks allow you to use state and lifecycle features in functional components. Sometimes, multiple components need the same logic, such as fetching data, managing forms, or handling animations.

Instead of repeating code, Custom Hooks allow you to extract reusable logic into a separate function.

What Are Custom Hooks?

A Custom Hook is a JavaScript function whose name starts with use and can call other hooks inside it.

  • They let you share logic across multiple components.
  • They do not render anything themselves, they just return state, functions, or values.
  • They follow the same rules as built-in hooks (e.g., only call hooks at the top level).

Syntax:

function useCustomHook() {
  // Use other hooks like useState, useEffect
  const [state, setState] = useState(initialValue);

  // Return values/functions
  return { state, setState };
}

Why Use Custom Hooks?

  • Avoid code duplication across components
  • Encapsulate complex logic in one place
  • Make your components clean and readable
  • Maintain consistent state management

Example – Custom Hook for Fetching Data

Suppose multiple components need to fetch data from an API. Instead of repeating useState and useEffect, we can create a useFetch hook.

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 {
        setLoading(true);
        const response = await fetch(url);
        const result = await response.json();
        setData(result);
      } catch (err) {
        setError(err);
      } finally {
        setLoading(false);
      }
    };
    fetchData();
  }, [url]);

  return { data, loading, error };
}

export default useFetch;

Using the Custom Hook in a Component

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

function Users() {
  const { data, loading, error } = useFetch("<https://jsonplaceholder.typicode.com/users>");

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

  return (
    <ul>
      {data.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}

export default Users;
  • useFetch handles all fetching logic.
  • The Users component only consumes the returned values.
  • This reduces duplication and makes your code cleaner and reusable.

Other Examples of Custom Hooks

  • useLocalStorage → Sync state with localStorage
  • useForm → Handle form state and validation
  • useWindowSize → Track window dimensions
  • usePrevious → Store previous state or props

Article 0 of 0