Custom Hooks in React

Custom Hooks in React

Custom hooks in React are reusable functions that encapsulate logic using React’s built-in hooks (like useState, useEffect, useRef, etc.). They allow you to extract component logic into reusable functions, making your components cleaner and more maintainable.

Why Use Custom Hooks?

  1. Reusability – Avoid repeating the same logic in multiple components.
  2. Separation of Concerns – Keeps component logic separate from UI rendering.
  3. Code Readability – Makes components more readable and easier to maintain.
  4. Stateful Logic Sharing – Unlike HOCs and render props, custom hooks allow logic sharing without altering component structure.


How to Create a Custom Hook

A custom hook is just a JavaScript function whose name starts with use and may call other hooks inside.

Example 1: useCounter Hook

A simple custom hook to manage a counter.

import { useState } from "react";

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

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

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

export default useCounter;
        

Usage in a Component

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

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

  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;
        

Example 2: useFetch Hook

A custom hook for fetching data from an API.

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.message);
      } finally {
        setLoading(false);
      }
    };

    fetchData();
  }, [url]);

  return { data, loading, error };
}

export default useFetch;
        

Usage in a Component

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

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

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

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

export default UsersList;
        

Example 3: useLocalStorage Hook

A hook to store and retrieve values from localStorage.

import { useState, useEffect } from "react";

function useLocalStorage(key, initialValue) {
  const [value, setValue] = useState(() => {
    const storedValue = localStorage.getItem(key);
    return storedValue ? JSON.parse(storedValue) : initialValue;
  });

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

  return [value, setValue];
}

export default useLocalStorage;
        

Usage in a Component

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

function ThemeSwitcher() {
  const [theme, setTheme] = useLocalStorage("theme", "light");

  return (
    <div>
      <p>Current Theme: {theme}</p>
      <button onClick={() => setTheme(theme === "light" ? "dark" : "light")}>
        Toggle Theme
      </button>
    </div>
  );
}

export default ThemeSwitcher;
        

Best Practices for Custom Hooks

  • Always start the name with use (e.g., useAuth, useTheme).
  • Use built-in hooks inside custom hooks (e.g., useState, useEffect).
  • Keep them reusable – Avoid making them too specific to a single component.
  • Encapsulate logic properly – Don't directly modify the component state inside a custom hook.
  • Use dependencies wisely – Be careful with dependencies in useEffect.

要查看或添加评论,请登录

Himmatlal Parmar的更多文章

社区洞察

其他会员也浏览了