DEV Community

Cover image for ✨ 17 React Hooks That Power 90% of Modern Components
Ndeye Fatou Diop
Ndeye Fatou Diop

Posted on • Originally published at frontendjoy.com

✨ 17 React Hooks That Power 90% of Modern Components

New to React?

If yes, you’ve probably wondered what hooks you really need—or worse, you’ve been copying the same logic over and over without realizing it.

This post covers all the React hooks you’ll likely need in your project.

Let’s dive in 🎉.


📚 Download my FREE 101 React Tips And Tricks Book for a head start.


1. useState

This hook is unavoidable.

Whenever you need dynamic state that persists across re-renders, this is the one.

const [count, setCount] = useState(0);
Enter fullscreen mode Exit fullscreen mode

2. useReducer

Once your state becomes complex (e.g. multiple correlated fields), useReducer becomes your friend.

It also pairs really well with useContext, letting you update state with simple dispatch calls.

const reducer = (state, action) => {
  switch (action.type) {
    case "addTodo":
      return { todos: [...state.todos, action.todo] };
    case "removeTodo":
      // TODO: Implement logic
    case "toggleTodo":
      // TODO: Implement logic
    default:
      return state;
  }
};

const [state, dispatch] = useReducer(reducer, { todos: [] });
Enter fullscreen mode Exit fullscreen mode

3. useContext

When prop drilling gets out of hand, this hook saves the day.

Prop drilling = passing props through multiple layers just to reach a deeply nested component.

Use useContext to:

  • manage global state in small apps

  • share data like the authenticated user

  • avoid passing props manually everywhere

const UserContext = createContext();

function App() {
  const user = useUser();
  return (
    <UserContext.Provider value={user}>
      {/* ... */}
    </UserContext.Provider>
  );
}

function Profile() {
  const user = useContext(UserContext);
  return <div>Hello {user.name}</div>;
}
Enter fullscreen mode Exit fullscreen mode

4. useEffect

You should avoid it 99% of the time.

(See: You Might Not Need an Effect)

But in real life, you’ll still need it—especially for things like syncing with external systems.

function useSetDocumentTitle(title: string) {
  useEffect(() => {
    document.title = title;
  }, [title]);
}
Enter fullscreen mode Exit fullscreen mode

5. useRef

You should never directly manipulate the DOM in React.

But when you must (e.g. for canvas, chart libraries…), useRef is the safe way.

function ExampleChart({ data }) {
  const canvasRef = useRef();

  useEffect(() => {
    const ctx = canvasRef.current;
    if (!ctx) return;

    const chart = new Chart(ctx, {
      type: "bar",
      data: {
        labels: data.map((row) => row.year),
        datasets: [{ label: "Likes", data: data.map((r) => r.count) }],
      },
    });

    return () => chart.destroy();
  }, []);

  return <canvas ref={canvasRef} />;
}
Enter fullscreen mode Exit fullscreen mode

6. useMemo / useCallback

These may become optional thanks to the new React Compiler—but for now, they’re still useful.

Use useMemo when:

  • an expensive computation should not re-run on every render

  • you're memoizing a non-primitive dependency

  • you're passing values to memo-wrapped components

Use useCallback to memoize functions.

const total = useMemo(() => computeTotal(items), [items]);

const handleClick = useCallback(() => {
  console.log("clicked");
}, []);
Enter fullscreen mode Exit fullscreen mode

7. useLayoutEffect

This one is rare but useful.

It runs before paint, which helps prevent layout shifts or flickering UI.

See real examples here: No more flickering UI

If you’re not comfortable with React components lifecycle, check my post ✨ React Lifecycle in 3 Minutes 😉.

useLayoutEffect(() => {
  const height = ref.current.offsetHeight;
  setHeight(height);
}, []);
Enter fullscreen mode Exit fullscreen mode

8. useSWR / useQuery

SWR and TanStack Query are becoming the standard for fetching data in React.

SWR is simpler and great for most use cases while TanStack Query is more complex and powerful.

SWR

const fetcher = (url) => fetch(url).then((res) => res.json());

const { data, error, isLoading } = useSWR("/api/user", fetcher);
Enter fullscreen mode Exit fullscreen mode

TanStack Query

const getUser = () => fetch("/api/user").then((res) => res.json());

const { data, isLoading } = useQuery({
  queryKey: ["user"],
  queryFn: getUser,
});
Enter fullscreen mode Exit fullscreen mode

9. useSelector, useDispatch, or other state hooks

Sometimes React’s built-in state tools aren’t enough.

You’ll then see these hooks depending on the state library:


10. useNavigate

React Router is very popular.

So is its navigation hook:

const navigate = useNavigate();
navigate("/profile");
Enter fullscreen mode Exit fullscreen mode

Now, let’s talk about hooks I reach for in nearly every app—even though they’re not built into React.


11. useBoolean

One of my all-time favorites.

It makes managing boolean state super clean.

const { value: isOpen, setFalse, toggle } = useBoolean();

return (
  <>
    <button onClick={toggle}>
      {isOpen ? "Close form" : "Open form"}
    </button>
    <Dialog isOpen={isOpen} onClose={setFalse}>
      {/* Form content */}
    </Dialog>
  </>
);
Enter fullscreen mode Exit fullscreen mode

12. useCopyToClipboard

Perfect for "copy" buttons.

const [copiedText, copy] = useCopyToClipboard();

const handleCopy = () => {
  copy("Hello World").catch(err => {
    errorToast("Failed to copy!", err);
  });
};

return (
  <>
    <button onClick={handleCopy}>Copy</button>
    {copiedText && <span>Copied!</span>}
  </>
);
Enter fullscreen mode Exit fullscreen mode

13. usePrevious

Use this to compare current vs. previous values.

Great for triggering actions based on changes.

const prevCount = usePrevious(count);
const didIncrease = prevCount !== undefined && count > prevCount;

useEffect(() => {
  if (didIncrease) {
    console.log("Count increased!");
  }
}, [didIncrease]);
Enter fullscreen mode Exit fullscreen mode

14. useDebounce

Debounce your requests to avoid unnecessary API calls.

const [query, setQuery] = useState("");
const [debouncedQuery] = useDebounce(query, 500);

const { data } = useSWR(`/api/search?q=${debouncedQuery}`, fetcher);

return (
  <> 
    <input
      value={query}
      onChange={(e) => setQuery(e.target.value)}
      placeholder="Search..."
    />
    {/* TODO: Show data */}
  </>

);
Enter fullscreen mode Exit fullscreen mode

15. useMediaQuery

Want to render different things based on screen size? This hook is for you.

const isMobile = useMediaQuery("(max-width: 768px)");

return <div>{isMobile ? "Mobile View" : "Desktop View"}</div>;
Enter fullscreen mode Exit fullscreen mode

16. useResizeObserver

Useful for responsive layouts or libraries like react-window.

const ref = useRef(null);
const { width = 0, height = 0 } = useResizeObserver({ ref });

return (
  <div ref={ref}>
    Width: {width}, Height: {height}
  </div>
);
Enter fullscreen mode Exit fullscreen mode

17. useLocalStorage

Store and sync data with localStorage easily.

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

return (
  <button onClick={() => setTheme(theme === "light" ? "dark" : "light")}>
    Switch to {theme === "light" ? "dark" : "light"}
  </button>
);
Enter fullscreen mode Exit fullscreen mode

Summary

That’s it!

These 17 hooks are more than enough to cover most use cases in any React app.

Pick your favorites and use them in your next project 😉.


If you're learning React, download my 101 React Tips & Tricks book for FREE.

If you like articles like this, join my FREE newsletter, FrontendJoy.

If you want daily tips, find me on X/Twitter or Bluesky.

Top comments (11)

Collapse
 
anmolbaranwal profile image
Anmol Baranwal

Let’s agree, we have used useSWR so many times on the client side. The name just sounds cool for some reason.

Collapse
 
_ndeyefatoudiop profile image
Ndeye Fatou Diop

Ahah indeed! Such a quick way to get started!

Collapse
 
nevodavid profile image
Nevo David

pretty cool list, makes me wish i had this when i started out - you think getting better with react is more about just banging out projects or actually digging into stuff like this every day?

Collapse
 
_ndeyefatoudiop profile image
Ndeye Fatou Diop

Hello Nevo, super glad you like it!
I think it is a mix. Definitely build projects, but try to explore what is out there. That gives you more tools to use :)

Collapse
 
ruqaiya_beguwala profile image
Ruqaiya Beguwala

Awesome breakdown! As someone learning hooks, this is super helpful. I’ve been using useEffect everywhere—time to explore all these as well.

Collapse
 
_ndeyefatoudiop profile image
Ndeye Fatou Diop

Super glad you like them! Oh definitely try to reduce the number of times you use effect ;)

Collapse
 
dotallio profile image
Dotallio

This list is ridiculously useful, especially the bonus utility hooks! Curious - which one do you personally use the most in your day-to-day projects?

Collapse
 
_ndeyefatoudiop profile image
Ndeye Fatou Diop

Super glad you like them! Thanks! If I had to give a top 5, it would be:

  • useState
  • a variant of useSWR/useQuery (I use GraphQL for data loading)
  • useSelector (because I work in a complex React app)
  • useBoolean
  • useRef
Collapse
 
oliver_gm profile image
Oliver Gm

Looks like a great one for the beginners 😁

Collapse
 
_ndeyefatoudiop profile image
Ndeye Fatou Diop

Thanks!

Collapse
 
blenderman profile image
BBM

Which of these hooks do you find yourself using the most in your own React projects?