Since their introduction, React Hooks have fundamentally changed how we write React components. As of 2025, they are the standard for building functional, stateful, and clean components, having almost entirely replaced class-based components in modern development. This tutorial provides a deep dive into the most essential hooks, complete with up-to-date examples and best practices.
What Are React Hooks?
Hooks are functions that let you “hook into” React state and lifecycle features from function components. They allow you to use state and other React features without writing a class. This leads to more readable, reusable, and organized code.
1. `useState`: The Foundation of State
The useState
hook is the most basic and common hook. It allows you to add a state variable to your functional components.
How it works: You call useState
with an initial value. It returns an array containing two elements: the current state value and a function to update it.
import React, { useState } from 'react';
function Counter() {
// The 'count' state variable is initialized to 0
// 'setCount' is the function to update it
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
2. `useEffect`: Handling Side Effects
The useEffect
hook lets you perform side effects in your components. Common side effects include fetching data, setting up subscriptions, and manually changing the DOM.
How it works: You pass a function to useEffect
. This function will run after the component renders. By providing a dependency array, you can control when the effect re-runs.
import React, { useState, useEffect } from 'react';
function UserData({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
// This function is the effect
const fetchUser = async () => {
const response = await fetch(`https://api.example.com/users/${userId}`);
const data = await response.json();
setUser(data);
};
fetchUser();
// The effect re-runs ONLY when 'userId' changes
}, [userId]);
if (!user) {
return <div>Loading...</div>;
}
return <div>Hello, {user.name}</div>;
}
3. `useContext`: Avoiding Prop Drilling
The useContext
hook allows you to subscribe to React context without introducing nesting. It makes it easy to pass data through the component tree without having to pass props down manually at every level.
import React, { useContext, createContext } from 'react';
// 1. Create a context
const ThemeContext = createContext('light');
// 2. Provide the context value at a high level
function App() {
return (
<ThemeContext.Provider value='dark'>
<Toolbar />
</ThemeContext.Provider>
);
}
// 3. Consume the context in a child component
function Toolbar() {
const theme = useContext(ThemeContext);
return <div>Current theme: {theme}</div>;
}
4. `useReducer`: For Complex State Logic
For components with complex state logic or where the next state depends on the previous one, useReducer
is often preferred over useState
. It's inspired by Redux and uses a reducer function to manage state transitions.
import React, { useReducer } from 'react';
const initialState = { count: 0 };
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
throw new Error();
}
}
function ReducerCounter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
Count: {state.count}
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
</>
);
}
5. `useCallback` & `useMemo`: Performance Optimization
These hooks are used to optimize performance by preventing unnecessary re-renders.
useMemo
: Memoizes a value. It recomputes the value only when one of its dependencies has changed. Useful for expensive calculations.useCallback
: Memoizes a function. It returns a memoized version of the callback that only changes if one of the dependencies has changed. This is useful when passing callbacks to optimized child components.
Comments
Post a Comment