Hooks revolutionized React development by allowing functional components to elegantly manage state, side effects, and complex logic. With React 19, new hooks were introduced to further streamline the workflow. In this article, we will explore classic hooks, advanced hooks, and what's new in version 19 with practical examples.
Basic React Hooks
useState: Simple State Management
Manages local states in functional components. Ideal for values that change over time.
Example: Interactive Counter
import { useState } from 'react';
function Counter() { const [count, setCount] = useState(0);
return (
You clicked {count} times
<button onClick={() => setCount(count + 1)}> IncrementuseEffect: Side Effects
Executes code after rendering, such as API calls or DOM manipulation.
Example: Fetching Data from an API
import { useState, useEffect } from 'react';
function UserList() { const [users, setUsers] = useState([]);
useEffect(() => { fetch('https://api.example.com/users') .then(response => response.json()) .then(data => setUsers(data)); }, []); // Execute only once
return (
-
{users.map(user => (
- {user.name} ))}
useContext: Global State Sharing
Accesses context values without prop drilling.
Example: Dark/Light Theme
import { createContext, useContext, useState } from 'react';
const ThemeContext = createContext();
function App() { const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider value=>
function Toolbar() { const { theme, setTheme } = useContext(ThemeContext);
return ( <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}> Switch to theme {theme === 'light' ? 'dark' : 'light'} ); }
useRef: Mutable References
Stores values that persist between renders without causing re-renders.
Example: Focus on Input
import { useRef } from 'react';
function TextInput() { const inputRef = useRef(null);
const focusInput = () => { inputRef.current.focus(); };
return (
Advanced and Customized Hooks
useReducer: Complex State
Manages states with more elaborate logic, similar to Redux.
Example: Task List
import { useReducer } from 'react';
function todosReducer(state, action) { switch (action.type) { case 'ADD_TODO': return [...state, { text: action.text, completed: false }]; case 'TOGGLE_TODO': return state.map((todo, index) => index === action.index ? { ...todo, completed: !todo.completed } : todo ); default: return state; } }
function TodoApp() { const [todos, dispatch] = useReducer(todosReducer, []);
const handleSubmit = (e) => { e.preventDefault(); dispatch({ type: 'ADD_TODO', text: e.target.elements.todo.value }); e.target.reset(); };
return (
useMemo and useCallback: Performance Optimization
- useMemo: Memorizes calculated values.
- useCallback: Memorizes functions.
Example: Heavy Calculation
import { useMemo, useState } from 'react';
function ExpensiveComponent({ list }) { const sortedList = useMemo(() => { console.log('Ordering list...'); return [...list].sort(); }, [list]);
return
Custom Hooks: Logic Reuse
Example: useFetch for HTTP Requests
import { useState, useEffect } from 'react';
function useFetch(url) { const [data, setData] = useState(null); const [loading, setLoading] = useState(true);
useEffect(() => { fetch(url) .then(res => res.json()) .then(data => { setData(date); setLoading(false); }); }, [url]);
return { data, loading }; }
// Usage in the component:
function UserProfile({ userId }) {
const { data: user, loading } = useFetch(https://api.example.com/users/${userId});
if (loading) return
New React 19 Hooks
useOptimistic: Optimistic Updates
Updates UI before server commit, rolling back in case of failure.
Example: Optimistic Comment Addition
import { useOptimistic } from 'react';
function CommentForm({ onSubmit }) { const [optimisticComments, addOptimisticComment] = useOptimistic( [], (state, newComment) => [...state, { text: newComment, sending: true }] );
const handleSubmit = async (e) => { e.preventDefault(); const formData = new FormData(e.target); const comment = formData.get('comment');
addOptimisticComment(comment);
try {
await onSubmit(comment);
} catch (error) {
// Revert the UI if the request fails
}
};
return (
useResource: Integration with Suspense
Manages asynchronous data declaratively.
Example: Data Loading with Fallback
import { useResource, Suspense } from 'react';
function fetchUser(id) { // Returns a promise }
function UserProfile({ userId }) { const userResource = useResource(() => fetchUser(userId));
return
// Usage in the parent component: <Suspense fallback={
useEventListener: Simplified Event Listeners
Manages event listeners cleanly.
Example: Monitor Window Size
import { useEventListener } from 'react';
function WindowSize() { const [size, setSize] = useState({ width: window.innerWidth, height: window.innerHeight });
useEventListener('resize', () => { setSize({ width: window.innerWidth, height: window.innerHeight }); });
return
useMediaQuery: Responsive Design
Reacts to changes in media queries.
Example: Dark Theme with System Preference
import { useMediaQuery } from 'react';
function DarkModeToggle() { const prefersDark = useMediaQuery('(prefers-color-scheme: dark)'); const [isDark, setIsDark] = useState(prefersDark);
// Update the site theme here...
return ( <button onClick={() => setIsDark(!isDark)}> {isDark? 'Disable dark mode' : 'Enable dark mode'} ); }
useErrorBoundary: Elegant Error Handling
Catches errors in child components.
Example: Custom Error Threshold
import { useErrorBoundary } from 'react';
function ErrorProneComponent() { const { ErrorBoundary, didCatch, error } = useErrorBoundary();
return didCatch ? (
Conclusion
React hooks continue to evolve, bringing powerful tools to simplify development. With React 19, features like useOptimistic and useResource elevate the user experience by handling asynchronous operations fluidly, while hooks like useMediaQuery and useEventListener make it easier to create adaptive interfaces.
By mastering these hooks, from the basics to the latest, you will be equipped to build more robust, performant and easier to maintain applications. Try integrating these techniques into your projects and see how they transform your workflow! 🚀
Also read
- TypeScript for Applications: TypeScript Development Guide
- How to Create a Website: Complete Guide from Zero to Ar
- How to Make a Professional Website: Complete Guide
- Creating Professional Websites: Complete Web Development Guide
- Modern Web Development in 2025: Trends, Tools and Innovative Strategies
- UX Best Practices for Complex Forms with React Hook Form
