Quiz

What are the benefits of using hooks in React?

Topics
React

TL;DR

Hooks let function components use state, context, refs, effects, and other React features without classes. Custom Hooks compose reusable stateful logic without adding wrapper components. React 19 added Hooks such as useActionState and useOptimistic, while React DOM provides useFormStatus. React 19's similarly named use(resource) is an API rather than a Hook and follows different call-order rules.


Benefits of using hooks in React

Hooks let function components compose stateful behavior while keeping related setup, updates, and cleanup together.

Why hooks were introduced

Before hooks (React 16.8, Feb 2019), the main ways to share stateful logic between components were higher-order components (HOCs) and render props. Repeated use of either pattern could produce deeply nested wrapper trees and obscure data flow in React DevTools. Class components also required this handling and often split one synchronization concern across componentDidMount, componentDidUpdate, and componentWillUnmount.

Hooks let components compose stateful logic through functions without adding wrapper components or relying on class lifecycle methods.

Reusable logic via custom hooks

Custom hooks let you extract a related combination of state, Effects, and other hooks into a function that components can call. Unlike an HOC, each custom Hook adds no wrapper component to the rendered tree.

import { useSyncExternalStore } from 'react';
function subscribe(callback) {
window.addEventListener('online', callback);
window.addEventListener('offline', callback);
return () => {
window.removeEventListener('online', callback);
window.removeEventListener('offline', callback);
};
}
function getSnapshot() {
return navigator.onLine;
}
function getServerSnapshot() {
return true;
}
function useOnlineStatus() {
return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
}
function StatusBar() {
const isOnline = useOnlineStatus();
return <div>{isOnline ? 'Online' : 'Offline'}</div>;
}

This version uses useSyncExternalStore because online status is a browser value that changes outside React. The server snapshot also avoids reading navigator during server rendering and gives hydration a deterministic initial value.

Simplified state management

useState adds local state to any function component without converting it to a class:

import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount((value) => value + 1)}>{count}</button>
);
}

For more complex state transitions, useReducer gives you a Redux-style reducer locally to a component or feature.

Side effects without lifecycle methods

useEffect replaces componentDidMount, componentDidUpdate, and componentWillUnmount with a single API where setup and cleanup live next to each other instead of being scattered across three methods:

import { useEffect } from 'react';
import { createConnection } from './chat-api';
function ChatRoom({ roomId }) {
useEffect(() => {
const connection = createConnection(roomId);
connection.connect();
return () => connection.disconnect();
}, [roomId]);
return <h1>Room: {roomId}</h1>;
}

No more this

Function components and hooks have no this, so there's nothing to bind, no .bind(this) in constructors, and no surprises about what this refers to in a callback.

React 19 Hooks and APIs unlock new patterns

React 19 adds several Hooks and related APIs that solve problems custom Hooks alone could not:

  • use(promise) — read a promise (or context) inside a component, integrating with Suspense for loading states.
  • useActionState — manage a form action's state (pending, error, result) with a single hook.
  • useFormStatus — read the pending state of the nearest parent <form> from a child, e.g. to disable a submit button.
  • useOptimistic — show an optimistic UI update while a mutation is in flight, automatically reverting on failure.

React Compiler 1.0 can additionally reduce manual useMemo/useCallback work in compatible code when the optional build-time optimizer is enabled.

Further reading

Exercises

Check your understanding
Beta
Check your understanding Exercise
Check your understanding Exercise

Two function components need the same subscription lifecycle but render completely different markup. What is the main benefit of extracting a custom Hook?