React12 min read18,234 views

React Hooks: A Complete Guide for 2024

Master React Hooks from useState to custom hooks. Learn best practices, common patterns, and advanced techniques for building modern React applications.

Youssef Boubli

Youssef Boubli

March 15, 2024

Share:
React Hooks: A Complete Guide for 2024

Introduction

React Hooks revolutionized how we write React components. Introduced in React 16.8, hooks allow you to use state and other React features without writing a class. In this comprehensive guide, we'll explore all the essential hooks and advanced patterns.

Why Hooks?

Before hooks, stateful logic was tied to class components. This led to:

  • Complex components that were hard to understand
  • Confusing this binding in JavaScript
  • Difficulty reusing stateful logic between components

Hooks solve these problems by letting you use state and lifecycle features in functional components.

useState: Managing State

The most fundamental hook. It lets you add state to functional components.

javascript

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)}>
10 Increment
11 </button>
12 </div>
13 );
14}

#

Best Practices for useState

1. Use multiple state variables for unrelated data

2. Group related state in objects

3. Use functional updates when new state depends on old state

useEffect: Side Effects

useEffect handles side effects like data fetching, subscriptions, and DOM manipulation.

javascript

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
16 fetchUser();
17 }, [userId]); // Dependency array
18
19 if (loading) return <div>Loading...</div>;
20 return <div>{user.name}</div>;
21}

#

Cleanup Functions

Always clean up subscriptions and timers:

javascript

1useEffect(() => {
2 const subscription = props.source.subscribe();
3 return () => {
4 subscription.unsubscribe();
5 };
6}, [props.source]);

useContext: Sharing State

Share state across components without prop drilling.

javascript

1import { createContext, useContext, useState } from 'react';
2
3const ThemeContext = createContext();
4
5function ThemeProvider({ children }) {
6 const [theme, setTheme] = useState('dark');
7
8 return (
9 <ThemeContext.Provider value={{ theme, setTheme }}>
10 {children}
11 </ThemeContext.Provider>
12 );
13}
14
15function ThemedButton() {
16 const { theme, setTheme } = useContext(ThemeContext);
17
18 return (
19 <button
20 style={{ background: theme === 'dark' ? '#333' : '#fff' }}
21 onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}
22 >
23 Toggle Theme
24 </button>
25 );
26}

Custom Hooks

Extract reusable logic into custom hooks.

javascript

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 setStoredValue(value);
13 window.localStorage.setItem(key, JSON.stringify(value));
14 };
15
16 return [storedValue, setValue];
17}
18
19// Usage
20const [name, setName] = useLocalStorage('name', 'Guest');

Conclusion

React Hooks provide a powerful and clean way to manage state and side effects. Master these patterns and you'll write more maintainable React applications.

Tags

ReactHooksJavaScriptFrontendWeb Development
Youssef Boubli

About the Author

Youssef Boubli

Front End Developer & UI/UX Designer from Morocco

View Full Profile →