React - Hooks: Complete Index
They allow you to use React state and features in functional components, making the code simpler and more reusable.
Organization of Hooks
This section is organized into several specialized chapters for better understanding:
📚 Basic Hooks
15.0.4.0 - useState
- Local state in functional components
- Management of state updates
- Optimization and best practices
- Practical examples with objects and arrays
15.0.4.1 - useEffect
- Side effects and lifecycle
- Common patterns: fetch, timers, events
- Dependencies and optimizations
- Cleanup and memory leak management
15.0.4.2 - useRef
- Direct DOM references
- Mutable values without re-render
- Advanced use cases: timers, intersection observer
- Difference with useState
⚡ Performance Hooks
15.0.4.3 - useMemo
- Memoization of expensive calculations
- Optimization of objects and arrays
- When and how to use useMemo
- Impact on performance
15.0.4.4 - useCallback
- Memoization of functions
- Avoiding unnecessary re-renders
- Optimization of child components
- Patterns with events
🏗️ State Management Hooks
15.0.4.5 - useReducer
- Complex state management
- Integrated Redux-like pattern
- Actions and reducers
- Use cases vs useState
15.0.4.6 - useContext
- Sharing data between components
- Solving prop drilling
- Context API and providers
- Patterns with multiple contexts
🚀 Advanced Hooks
15.0.4.7 - Advanced Hooks
- useLayoutEffect: DOM synchronization
- useId: unique identifiers
- useTransition: non-blocking transitions
- useDeferredValue: deferred values
🎨 Custom Hooks
15.0.4.8 - Custom Hooks
- Creating your own hooks
- Reusability and shared logic
- Common patterns: API, UI, utilities
- Composition and best practices
Quick Overview
Native React Hooks
import {
useState, // Local state
useEffect, // Side effects
useRef, // DOM references/mutable values
useMemo, // Memoization of calculations
useCallback, // Memoization of functions
useReducer, // Complex state
useContext, // Global context
useLayoutEffect, // Synchronous effects
useId, // Unique identifiers
useTransition, // UI Transitions
useDeferredValue // Deferred values
} from 'react'
Custom Hook Example
// Simple custom hook
function useCounter(initialValue = 0) {
const [count, setCount] = useState(initialValue)
const increment = useCallback(() => setCount(c => c + 1), [])
const decrement = useCallback(() => setCount(c => c - 1), [])
const reset = useCallback(() => setCount(initialValue), [initialValue])
return { count, increment, decrement, reset }
}
// Usage
function App() {
const { count, increment, decrement, reset } = useCounter(10)
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>+1</button>
<button onClick={decrement}>-1</button>
<button onClick={reset}>Reset</button>
</div>
)
}
Rules of Hooks
⚠️ Important Rules
- Always at the root level: never in loops, conditions, or nested functions
- Only in React components or other custom hooks
- Constant order: the order of calls must be identical on each render
- Naming: custom hooks start with "use"
// ✅ GOOD
function GoodComponent() {
const [count, setCount] = useState(0)
const [name, setName] = useState('')
useEffect(() => {
document.title = `${name} - ${count}`
}, [name, count])
return <div>...</div>
}
// ❌ BAD
function BadComponent({ condition }) {
const [count, setCount] = useState(0)
if (condition) {
const [name, setName] = useState('') // ❌ Conditional Hook!
useEffect(() => {}) // ❌ Conditional Hook!
}
return <div>...</div>
}
Common Patterns
Data Fetching
function useApiData(url) {
const [data, setData] = useState(null)
const [loading, setLoading] = useState(true)
const [error, setError] = useState(null)
useEffect(() => {
fetch(url)
.then(res => res.json())
.then(setData)
.catch(setError)
.finally(() => setLoading(false))
}, [url])
return { data, loading, error }
}
Local State Management
function useFormState(initialState) {
const [values, setValues] = useState(initialState)
const [errors, setErrors] = useState({})
const setValue = useCallback((name, value) => {
setValues(prev => ({ ...prev, [name]: value }))
setErrors(prev => ({ ...prev, [name]: null }))
}, [])
const setError = useCallback((name, error) => {
setErrors(prev => ({ ...prev, [name]: error }))
}, [])
return { values, errors, setValue, setError }
}
UI State
function useToggle(initialValue = false) {
const [value, setValue] = useState(initialValue)
const toggle = useCallback(() => setValue(v => !v), [])
return [value, toggle]
}
function useModal() {
const [isOpen, setIsOpen] = useState(false)
const open = useCallback(() => setIsOpen(true), [])
const close = useCallback(() => setIsOpen(false), [])
return { isOpen, open, close }
}
Class → Hooks Migration
Before (Class Component)
class Counter extends Component {
constructor(props) {
super(props)
this.state = { count: 0 }
}
componentDidMount() {
document.title = `Count: ${this.state.count}`
}
componentDidUpdate() {
document.title = `Count: ${this.state.count}`
}
increment = () => {
this.setState(prev => ({ count: prev.count + 1 }))
}
render() {
return (
<div>
<p>{this.state.count}</p>
<button onClick={this.increment}>+1</button>
</div>
)
}
}
After (Hooks)
function Counter() {
const [count, setCount] = useState(0)
useEffect(() => {
document.title = `Count: ${count}`
}, [count])
const increment = useCallback(() => {
setCount(prev => prev + 1)
}, [])
return (
<div>
<p>{count}</p>
<button onClick={increment}>+1</button>
</div>
)
}
Additional Resources
- 📚 Hooks API Reference
- 🎯 Rules of Hooks
- 💡 Building Custom Hooks
- 🔄 useHooks.com - Collection of useful hooks
- 🛠️ React Hook Form - Form management
- ⚡ TanStack Query - Hooks for the API