DEV Community

Atilla Baspinar
Atilla Baspinar

Posted on

08 - React: custom hooks

A custom hook is just a function whose name starts with use and that contains reusable React logic.

The main idea is to extract logic that is shared across components so we do not duplicate the same state and effects in multiple places.

Custom hooks can be used:

  • directly inside a component
  • inside another custom hook

As long as the hook follows the Rules of Hooks, it works the same way as built-in hooks.

1) Why custom hooks are useful

If several components need the same behavior, we can move that behavior into a custom hook.

Examples:

  • fetching data
  • managing a form
  • handling local storage
  • tracking window size
  • timer logic

This makes the component code cleaner and more reusable.

2) State inside a custom hook

A custom hook often uses useState, useEffect, or other hooks internally.

The important fact is:

  • state created inside a custom hook is still part of the calling component's React state lifecycle
  • updating that state causes the component to re-render, just like normal state in a component
import { useState } from 'react';

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

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

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

export default function App() {
  const { count, increment, decrement, reset } = useCounter(0);

  return (
    <>
      <p>Count: {count}</p>
      <button onClick={increment}>+</button>
      <button onClick={decrement}>-</button>
      <button onClick={reset}>Reset</button>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

This hook encapsulates the counter logic in one place and can be reused anywhere.

3) Returning state and setter functions

A custom hook usually returns values that the component can use.

For example, a hook can return:

  • state value
  • setter function
  • computed values
  • helper functions
import { useState } from 'react';

function useToggle(initialValue = false) {
  const [value, setValue] = useState(initialValue);

  const toggle = () => setValue((prev) => !prev);
  const open = () => setValue(true);
  const close = () => setValue(false);

  return { value, toggle, open, close };
}

export default function App() {
  const { value, toggle, open, close } = useToggle(false);

  return (
    <>
      <p>{value ? 'Open' : 'Closed'}</p>
      <button onClick={toggle}>Toggle</button>
      <button onClick={open}>Open</button>
      <button onClick={close}>Close</button>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

The set function can be used outside the custom hook, and when it updates the state, the component re-renders normally.

4) Important rule

A custom hook must itself follow the Rules of Hooks.

That means it can call hooks, but it must be used at the top level of a component or another custom hook, not inside a conditional or loop.

5) Summary

  • custom hooks are reusable pieces of React logic
  • they are useful for extracting repeated state/effect logic
  • they can call hooks like useState and useEffect
  • state inside a custom hook behaves like normal component state
  • return the values the component needs, such as state and update functions

This is one of the core patterns for writing cleaner React code: move repeatable logic into a hook, then use it in multiple components.

Top comments (0)