React Hooks: A Complete Guide for 2025
Master React Hooks with this comprehensive guide covering useState, useEffect, useContext, and custom hooks. Learn best practices and common patterns for modern React development.
React Hooks: A Complete Guide for 2025
React Hooks have revolutionized how we write React components. They allow us to use state and other React features in functional components, making our code more readable and maintainable.
What are React Hooks?
React Hooks are functions that allow you to "hook into" React state and lifecycle features from function components. They were introduced in React 16.8 and have become the standard way to write React components.
Basic Hooks
useState Hook
The useState
hook is the most basic hook that allows you to add state to functional components.
import React, { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
}
useEffect Hook
The useEffect
hook lets you perform side effects in functional components. It serves the same purpose as componentDidMount
, componentDidUpdate
, and componentWillUnmount
in React classes.
import React, { useState, useEffect } from "react";
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
}
Advanced Hooks
useContext Hook
The useContext
hook allows you to consume React context without nesting.
import React, { useContext } from "react";
import { ThemeContext } from "./theme-context";
function ThemedButton() {
const theme = useContext(ThemeContext);
return (
<button style={{ background: theme.background, color: theme.foreground }}>
I am styled by theme context!
</button>
);
}
useReducer Hook
The useReducer
hook is an alternative to useState
for managing complex state logic.
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 Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
Count: {state.count}
<button onClick={() => dispatch({ type: "decrement" })}>-</button>
<button onClick={() => dispatch({ type: "increment" })}>+</button>
</>
);
}
Custom Hooks
Custom hooks are a way to extract component logic into reusable functions.
import { useState, useEffect } from "react";
function useWindowSize() {
const [windowSize, setWindowSize] = useState({
width: undefined,
height: undefined,
});
useEffect(() => {
function handleResize() {
setWindowSize({
width: window.innerWidth,
height: window.innerHeight,
});
}
window.addEventListener("resize", handleResize);
handleResize();
return () => window.removeEventListener("resize", handleResize);
}, []);
return windowSize;
}
Best Practices
- Only call hooks at the top level: Don't call hooks inside loops, conditions, or nested functions.
- Only call hooks from React functions: Call hooks from React function components or custom hooks.
- Use the dependency array correctly: Always include all dependencies in the useEffect dependency array.
- Extract complex logic into custom hooks: This makes your components more readable and testable.
Conclusion
React Hooks have made functional components more powerful and easier to work with. They promote better code organization and reusability. By mastering hooks, you'll be able to write more maintainable and efficient React applications.
Remember to always follow the rules of hooks and use them appropriately in your components. With practice, you'll find that hooks make React development more enjoyable and productive.
Enjoyed this article?
If you found this post helpful, consider sharing it with your network or subscribing to my newsletter for more insights.