What are the benefits of using hooks in React?
TL;DR
Hooks let you use state and other React features in plain functions, without classes. They were introduced to solve real pain points in the class-component era — "wrapper hell" from HOCs and render props, the awkwardness of this binding, and the difficulty of sharing stateful logic between components. Custom hooks make that logic genuinely reusable through composition. React 19 expands the set further with hooks like use, useActionState, useOptimistic, and useFormStatus for promises, forms, and optimistic UI.
Benefits of using hooks in React
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. Both produced deeply nested component trees — the so-called "wrapper hell" you'd see in React DevTools — and made it hard to follow data flow. Class components also forced you to bind this for handlers, split related logic across componentDidMount/componentDidUpdate/componentWillUnmount, and made it nearly impossible to extract a piece of stateful behaviour without restructuring the component tree.
Hooks solve all of these by moving stateful logic into plain functions you can compose, with no this, no extra wrappers, and no lifecycle-method scatter.
Reusable logic via custom hooks
Custom hooks let you extract any combination of state, effects, and other hooks into a function that any component can call. This is composition rather than inheritance, and it scales much better than HOCs — you can use as many custom hooks in a component as you want without nesting.
function useOnlineStatus() {const [isOnline, setIsOnline] = useState(navigator.onLine);useEffect(() => {const on = () => setIsOnline(true);const off = () => setIsOnline(false);window.addEventListener('online', on);window.addEventListener('offline', off);return () => {window.removeEventListener('online', on);window.removeEventListener('offline', off);};}, []);return isOnline;}function StatusBar() {const isOnline = useOnlineStatus();return <div>{isOnline ? 'Online' : 'Offline'}</div>;}
Because custom hooks are just function calls, you also break complex components into smaller, named pieces of logic — making them easier to read.
Simplified state management
useState adds local state to any function component without converting it to a class:
const [count, setCount] = useState(0);
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:
useEffect(() => {// setup (mount + when dependencies change)return () => {// cleanup (unmount + before next run)};}, [dependencies]);
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 unlock new patterns
React 19 adds several hooks 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.
Combined with the React Compiler (RC/stable by 2026), these reduce a lot of the manual useMemo/useCallback and form-state boilerplate that earlier hook-based code needed.