React Hooks Complete Guide: useState, useEffect, and Best Practices 2025
React Hooks Complete Guide: useState, useEffect, and Best Practices 2025
React Hooks revolutionized React development by allowing functional components to manage state and side effects. This comprehensive guide covers everything you need to know about React Hooks in 2025.
What are React Hooks?
React Hooks are functions that let you "hook into" React features from functional components. Introduced in React 16.8, hooks allow you to use state and other React features without writing class components.
Why Use Hooks?
Basic React Hooks
1. useState Hook
useState allows functional components to manage local state:
1import { useState } from 'react';2 3function Counter() {4 const [count, setCount] = useState(0);5 6 return (7 <div>8 <p>Count: {count}</p>9 <button onClick={() => setCount(count + 1)}>Increment</button>10 <button onClick={() => setCount(count - 1)}>Decrement</button>11 <button onClick={() => setCount(0)}>Reset</button>12 </div>13 );14}useState with Objects:
1function UserForm() {2 const [user, setUser] = useState({3 name: '',4 email: '',5 age: 06 });7 8 const handleChange = (e) => {9 setUser({10 ...user,11 [e.target.name]: e.target.value12 });13 };14 15 return (2. useEffect Hook
useEffect handles side effects in functional components:
1import { useState, useEffect } from 'react';2 3function UserProfile({ userId }) {4 const [user, setUser] = useState(null);5 const [loading, setLoading] = useState(true);6 7 useEffect(() => {8 async function fetchUser() {9 setLoading(true);10 const response = await fetch(`/api/users/${userId}`);11 const data = await response.json();12 setUser(data);13 setLoading(false);14 }15 useEffect Cleanup:
1function Timer() {2 const [seconds, setSeconds] = useState(0);3 4 useEffect(() => {5 const interval = setInterval(() => {6 setSeconds(prev => prev + 1);7 }, 1000);8 9 // Cleanup function10 return () => clearInterval(interval);11 }, []); // Run once on mount12 13 return <div>Seconds: {seconds}</div>;14}3. useContext Hook
useContext accesses React context values:
1import { createContext, useContext } from 'react';2 3const ThemeContext = createContext('light');4 5function App() {6 return (7 <ThemeContext.Provider value="dark">8 <Toolbar />9 </ThemeContext.Provider>10 );11}12 13function Toolbar() {14 const theme = useContext(ThemeContext);15 return <div className={`theme-${theme}`}>Toolbar</div>;4. useReducer Hook
useReducer manages complex state logic:
1import { useReducer } from 'react';2 3const initialState = { count: 0 };4 5function reducer(state, action) {6 switch (action.type) {7 case 'increment':8 return { count: state.count + 1 };9 case 'decrement':10 return { count: state.count - 1 };11 case 'reset':12 return initialState;13 default:14 throw new Error();15 }Custom Hooks
Create reusable hooks for common logic:
1// Custom hook for API fetching2function useFetch(url) {3 const [data, setData] = useState(null);4 const [loading, setLoading] = useState(true);5 const [error, setError] = useState(null);6 7 useEffect(() => {8 async function fetchData() {9 try {10 setLoading(true);11 const response = await fetch(url);12 const json = await response.json();13 setData(json);14 setError(null);15 } catch (err) {Custom Hook for Local Storage:
1function useLocalStorage(key, initialValue) {2 const [storedValue, setStoredValue] = useState(() => {3 try {4 const item = window.localStorage.getItem(key);5 return item ? JSON.parse(item) : initialValue;6 } catch (error) {7 return initialValue;8 }9 });10 11 const setValue = (value) => {12 try {13 setStoredValue(value);14 window.localStorage.setItem(key, JSON.stringify(value));15 } catch (error) {Advanced Hooks
useMemo Hook
useMemo memoizes expensive calculations:
1import { useMemo } from 'react';2 3function ExpensiveComponent({ items, filter }) {4 const filteredItems = useMemo(() => {5 return items.filter(item => item.category === filter);6 }, [items, filter]); // Recalculate only when items or filter change7 8 return (9 <ul>10 {filteredItems.map(item => (11 <li key={item.id}>{item.name}</li>12 ))}13 </ul>14 );15}useCallback Hook
useCallback memoizes functions:
1import { useCallback, useState } from 'react';2 3function ParentComponent() {4 const [count, setCount] = useState(0);5 6 const handleClick = useCallback(() => {7 console.log('Clicked!', count);8 }, [count]); // Recreate function only when count changes9 10 return <ChildComponent onClick={handleClick} />;11}12 13function ChildComponent({ onClick }) {14 return <button onClick={onClick}>Click me</button>;15}useRef Hook
useRef persists values across renders:
1import { useRef, useEffect } from 'react';2 3function FocusInput() {4 const inputRef = useRef(null);5 6 useEffect(() => {7 inputRef.current.focus();8 }, []);9 10 return <input ref={inputRef} type="text" />;11}React Hooks Best Practices
1. Follow Rules of Hooks
1// Bad - Conditional hook2function Component({ condition }) {3 if (condition) {4 const [value, setValue] = useState(0); // Wrong!5 }6 return <div>Component</div>;7}8 9// Good - Always call hooks at top level10function Component({ condition }) {11 const [value, setValue] = useState(0);12 13 if (condition) {14 // Use condition in logic, not in hook call15 }2. Optimize useEffect Dependencies
Always include all dependencies in the dependency array:
1// Bad - Missing dependency2useEffect(() => {3 fetchData(userId);4}, []); // Missing userId5 6// Good - All dependencies included7useEffect(() => {8 fetchData(userId);9}, [userId]);3. Cleanup Side Effects
Always cleanup subscriptions, timers, and event listeners:
1useEffect(() => {2 const subscription = subscribe();3 const timer = setInterval(() => {}, 1000);4 window.addEventListener('resize', handleResize);5 6 return () => {7 subscription.unsubscribe();8 clearInterval(timer);9 window.removeEventListener('resize', handleResize);10 };11}, []);4. Use Custom Hooks for Reusability
Extract common logic into custom hooks:
1// Custom hook2function useDebounce(value, delay) {3 const [debouncedValue, setDebouncedValue] = useState(value);4 5 useEffect(() => {6 const timer = setTimeout(() => {7 setDebouncedValue(value);8 }, delay);9 10 return () => clearTimeout(timer);11 }, [value, delay]);12 13 return debouncedValue;14}15 Common React Hooks Patterns
Form Handling Hook:
1function useForm(initialValues) {2 const [values, setValues] = useState(initialValues);3 const [errors, setErrors] = useState({});4 5 const handleChange = (e) => {6 const { name, value } = e.target;7 setValues({ ...values, [name]: value });8 };9 10 const handleSubmit = (onSubmit) => (e) => {11 e.preventDefault();12 onSubmit(values);13 };14 15 return { values, errors, handleChange, handleSubmit };React Hooks Tools
Online React Hook Generator
Codev Nexus React Hook Generator - Free, instant React hook generation:
Try it: [codevnexus.com/tools/react-hook-generator](https://codevnexus.com/tools/react-hook-generator)
Conclusion
React Hooks provide a powerful and elegant way to manage state and side effects in functional components. Understanding hooks is essential for modern React development.
Key Takeaways:
Start using React Hooks today to write cleaner, more maintainable React code!
Resources
Master React Hooks for modern React development!
Enjoyed this article?
Support our work and help us create more free content for developers.
Stay Updated
Get the latest articles and updates delivered to your inbox.