React - Les Hooks : Index Complet
Ils permettent d'utiliser l'état et les fonctionnalités de React dans des composants fonctionnels, rendant le code plus simple et réutilisable.
Organisation des Hooks
Cette section est organisée en plusieurs chapitres spécialisés pour une meilleure compréhension :
📚 Hooks de Base
15.0.4.0 - useState
- État local dans les composants fonctionnels
- Gestion des mises à jour d'état
- Optimisation et bonnes pratiques
- Exemples pratiques avec objets et tableaux
15.0.4.1 - useEffect
- Effets de bord et cycle de vie
- Patterns courants : fetch, timers, événements
- Dependencies et optimisations
- Cleanup et gestion des fuites mémoire
15.0.4.2 - useRef
- Références DOM directes
- Valeurs mutables sans re-render
- Cas d'usage avancés : timers, intersection observer
- Différence avec useState
⚡ Hooks de Performance
15.0.4.3 - useMemo
- Mémorisation des calculs coûteux
- Optimisation des objets et tableaux
- Quand et comment utiliser useMemo
- Impact sur les performances
15.0.4.4 - useCallback
- Mémorisation des fonctions
- Éviter les re-renders inutiles
- Optimisation des composants enfants
- Patterns avec les événements
🏗️ Hooks de Gestion d'État
15.0.4.5 - useReducer
- Gestion d'état complexe
- Pattern Redux-like intégré
- Actions et reducers
- Cas d'usage vs useState
15.0.4.6 - useContext
- Partage de données entre composants
- Résoudre le prop drilling
- Context API et providers
- Patterns avec plusieurs contextes
🚀 Hooks Avancés
15.0.4.7 - Hooks Avancés
- useLayoutEffect : synchronisation DOM
- useId : identifiants uniques
- useTransition : transitions non-bloquantes
- useDeferredValue : valeurs différées
🎨 Hooks Personnalisés
15.0.4.8 - Custom Hooks
- Créer ses propres hooks
- Réutilisabilité et logique partagée
- Patterns courants : API, UI, utilitaires
- Composition et bonnes pratiques
Vue d'Ensemble Rapide
Hooks Natifs React
import {
useState, // État local
useEffect, // Effets de bord
useRef, // Références DOM/valeurs mutables
useMemo, // Mémorisation calculs
useCallback, // Mémorisation fonctions
useReducer, // État complexe
useContext, // Context global
useLayoutEffect, // Effets synchrones
useId, // Identifiants uniques
useTransition, // Transitions UI
useDeferredValue // Valeurs différées
} from 'react'
Exemple de Hook Personnalisé
// Hook personnalisé simple
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 }
}
// Utilisation
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>
)
}
Règles des Hooks
⚠️ Règles Importantes
- Toujours au niveau racine : jamais dans des boucles, conditions ou fonctions imbriquées
- Uniquement dans les composants React ou autres hooks personnalisés
- Ordre constant : l'ordre d'appel doit être identique à chaque render
- Nommage : les hooks personnalisés commencent par "use"
// ✅ BON
function GoodComponent() {
const [count, setCount] = useState(0)
const [name, setName] = useState('')
useEffect(() => {
document.title = `${name} - ${count}`
}, [name, count])
return <div>...</div>
}
// ❌ MAUVAIS
function BadComponent({ condition }) {
const [count, setCount] = useState(0)
if (condition) {
const [name, setName] = useState('') // ❌ Hook conditionnel !
useEffect(() => {}) // ❌ Hook conditionnel !
}
return <div>...</div>
}
Patterns Courants
Fetch de Données
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 }
}
State Management Local
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 }
}
Migration Class → Hooks
Avant (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>
)
}
}
Après (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>
)
}
Ressources Complémentaires
- 📚 Hooks API Reference
- 🎯 Rules of Hooks
- 💡 Building Custom Hooks
- 🔄 useHooks.com - Collection de hooks utiles
- 🛠️ React Hook Form - Gestion de formulaires
- ⚡ TanStack Query - Hooks pour l'API