DEV Community

Selahaddin Osmanoglu
Selahaddin Osmanoglu

Posted on

Part 10: Custom Hooks and Reusability – DRY Up Your React Logic

Welcome to Part 10 of the React for Beginners series!

As your app grows, you’ll find yourself repeating logic across components — like handling form inputs, toggling values, fetching data, etc.

Wouldn’t it be great if you could extract and reuse that logic?

You can — with custom hooks.


🧠 What Is a Custom Hook?

A custom hook is a JavaScript function that:

  • Starts with use
  • Uses other hooks inside it (like useState, useEffect, etc.)
  • Encapsulates reusable logic

Think of it like a function component with no UI — just logic.


✨ Example: useToggle Hook

Let’s say you want to toggle a boolean value (e.g., show/hide, like/unlike):

/hooks/useToggle.js

import { useState } from 'react';

function useToggle(initialValue = false) {
  const [value, setValue] = useState(initialValue);
  const toggle = () => setValue((v) => !v);
  return [value, toggle];
}

export default useToggle;
Enter fullscreen mode Exit fullscreen mode

Usage in a Component

import useToggle from './hooks/useToggle';

function ToggleBox() {
  const [isVisible, toggleVisible] = useToggle();

  return (
    <div>
      <button onClick={toggleVisible}>
        {isVisible ? 'Hide' : 'Show'} Message
      </button>
      {isVisible && <p>This is a toggled message!</p>}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

✅ Logic is clean and reusable!


📡 Example: useFetch Hook (Basic)

Fetching data is another good use case.

/hooks/useFetch.js

import { useState, useEffect } from 'react';

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

  useEffect(() => {
    setLoading(true);
    fetch(url)
      .then((res) => res.json())
      .then((json) => {
        setData(json);
        setLoading(false);
      });
  }, [url]);

  return { data, loading };
}

export default useFetch;
Enter fullscreen mode Exit fullscreen mode

Usage in a Component

import useFetch from './hooks/useFetch';

function RandomUser() {
  const { data, loading } = useFetch('https://randomuser.me/api/');

  if (loading) return <p>Loading...</p>;

  const user = data.results[0];
  return (
    <div>
      <p>{user.name.first} {user.name.last}</p>
      <img src={user.picture.medium} alt="User avatar" />
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

🪝 When Should You Create a Custom Hook?

  • You repeat the same hook-based logic in multiple components
  • The logic is self-contained and doesn’t depend on UI layout
  • You want cleaner, more maintainable code

🧩 Naming Convention

Always name custom hooks starting with use — like useToggle, useForm, useScroll, etc.

This lets React know it’s a hook and enforce rules accordingly.


✍️ Challenge for You

  • Create a useInput hook that manages the value and onChange for a form field.
  • Use it to build a reusable input component.
  • Bonus: Add a reset function to the hook!

✅ Summary

  • Custom hooks let you extract and reuse stateful logic.
  • They improve readability, reduce duplication, and promote clean code.
  • You can use built-in hooks inside custom ones (like useState, useEffect, etc.).
  • They don’t render anything — they just return data and functions.

🔜 What’s Next?

In Part 11, the final part of this series, we’ll give you a peek into advanced React topics like context, reducers, memoization, and more.

Your components are now smarter and your code is cleaner — that’s pro-level React thinking! 🧠💡

Top comments (0)