No articles found
Try different keywords or browse our categories
Getting Started with React Hooks in 2025
Learn how to use React Hooks effectively in your modern React applications with practical examples and best practices.
React Hooks revolutionized how we write React components by allowing us to use state and other React features without writing classes. In this comprehensive guide, we’ll explore the most important hooks and how to use them effectively in 2025.
What Are React Hooks?
Hooks are functions that let you “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.
useState: Managing Component State
The useState hook is the most fundamental hook for managing state in functional components.
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>
Increment
</button>
</div>
);
}
Best Practices for useState
Always use the functional update form when the new state depends on the previous state:
// Good
setCount(prevCount => prevCount + 1);
// Avoid
setCount(count + 1);
useEffect: Side Effects Made Easy
The useEffect hook lets you perform side effects in function components. It’s similar to componentDidMount, componentDidUpdate, and componentWillUnmount combined.
import { useState, useEffect } from 'react';
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function fetchUser() {
setLoading(true);
try {
const response = await fetch(`/api/users/${userId}`);
const data = await response.json();
setUser(data);
} catch (error) {
console.error('Error fetching user:', error);
} finally {
setLoading(false);
}
}
fetchUser();
}, [userId]);
if (loading) return <div>Loading...</div>;
if (!user) return <div>User not found</div>;
return (
<div>
<h1>{user.name}</h1>
<p>{user.email}</p>
</div>
);
}
useContext: Sharing Data Across Components
The useContext hook provides a way to pass data through the component tree without manually passing props at every level.
import { createContext, useContext, useState } from 'react';
const ThemeContext = createContext();
function ThemeProvider({ children }) {
const [theme, setTheme] = useState('light');
const toggleTheme = () => {
setTheme(prev => prev === 'light' ? 'dark' : 'light');
};
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
}
function ThemedButton() {
const { theme, toggleTheme } = useContext(ThemeContext);
return (
<button
onClick={toggleTheme}
style={{
background: theme === 'light' ? '#fff' : '#333',
color: theme === 'light' ? '#333' : '#fff'
}}
>
Toggle Theme
</button>
);
}
Custom Hooks: Reusable Logic
Creating custom hooks allows you to extract component logic into reusable functions.
function useLocalStorage(key, initialValue) {
const [storedValue, setStoredValue] = useState(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
console.error(error);
return initialValue;
}
});
const setValue = (value) => {
try {
const valueToStore = value instanceof Function
? value(storedValue)
: value;
setStoredValue(valueToStore);
window.localStorage.setItem(key, JSON.stringify(valueToStore));
} catch (error) {
console.error(error);
}
};
return [storedValue, setValue];
}
// Usage
function App() {
const [name, setName] = useLocalStorage('name', 'Guest');
return (
<input
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Enter your name"
/>
);
}
Common Pitfalls and How to Avoid Them
1. Missing Dependencies
Always include all dependencies in the dependency array of useEffect:
// Bad
useEffect(() => {
fetchData(userId);
}, []);
// Good
useEffect(() => {
fetchData(userId);
}, [userId]);
2. Infinite Loops
Be careful not to create infinite loops by updating state inside useEffect without proper dependencies:
// Bad - causes infinite loop
useEffect(() => {
setCount(count + 1);
});
// Good
useEffect(() => {
setCount(prevCount => prevCount + 1);
}, []);
Conclusion
React Hooks have made functional components more powerful and easier to work with. By mastering useState, useEffect, and useContext, along with creating custom hooks, you can build modern, maintainable React applications.
Remember to follow the Rules of Hooks:
- Only call hooks at the top level
- Only call hooks from React functions
- Use the ESLint plugin to enforce these rules
Happy coding!
Related Articles
How to integrate jsPDF Library in React to Edit PDF in Browser
Quick guide to using jsPDF in React applications for creating and editing PDF documents directly in the browser.
QR Codes with React: Quick Implementation
Build QR code scanner and generator in React. Simple setup with react-qr-code and html5-qrcode libraries.
jsPDF Tutorial: Generate PDF in Browser Using HTML & JavaScript (Full Working Example)
Learn to create PDFs directly in the browser with jsPDF. Step-by-step guide with working examples for invoices, tickets, and styled documents.