Les Hooks React avancés que vous devriez connaître
Explorez les hooks React avancés comme useCallback, useMemo et useRef pour optimiser vos composants et améliorer les performances.
Au-delà des hooks basiques useState et useEffect, React propose des hooks avancés qui permettent d'optimiser les performances et de gérer des cas d'usage complexes.
useCallback - Mémoriser les fonctions
useCallback permet de mémoriser une fonction pour éviter sa recréation à chaque rendu. C'est particulièrement utile lorsque vous passez des callbacks à des composants enfants optimisés.
Le problème
Sans useCallback, chaque rendu crée une nouvelle référence de fonction :
function Parent() {
const [count, setCount] = useState(0);
// ❌ Nouvelle fonction à chaque rendu
const handleClick = () => {
console.log('Clicked!');
};
return <Child onClick={handleClick} />;
}
La solution
function Parent() {
const [count, setCount] = useState(0);
// ✅ Même référence entre les rendus
const handleClick = useCallback(() => {
console.log('Clicked!');
}, []);
return <Child onClick={handleClick} />;
}
useMemo - Mémoriser les calculs coûteux
useMemo permet de mémoriser le résultat d'un calcul coûteux :
function ProductList({ products, filter }: Props) {
// Calcul mémorisé - ne s'exécute que si products ou filter change
const filteredProducts = useMemo(() => {
return products.filter((product) =>
product.name.toLowerCase().includes(filter.toLowerCase())
);
}, [products, filter]);
return (
<ul>
{filteredProducts.map((product) => (
<li key={product.id}>{product.name}</li>
))}
</ul>
);
}
Attention : N'utilisez pas
useMemopartout ! Réservez-le aux calculs vraiment coûteux.
useRef - Persister des valeurs
useRef a deux usages principaux :
- Accéder aux éléments DOM
- Persister des valeurs entre les rendus sans déclencher de re-rendu
Accès au DOM
function TextInput() {
const inputRef = useRef<HTMLInputElement>(null);
const focusInput = () => {
inputRef.current?.focus();
};
return (
<>
<input ref={inputRef} type="text" />
<button onClick={focusInput}>Focus</button>
</>
);
}
Valeur persistante
function Timer() {
const [count, setCount] = useState(0);
const intervalRef = useRef<NodeJS.Timeout | null>(null);
useEffect(() => {
intervalRef.current = setInterval(() => {
setCount((c) => c + 1);
}, 1000);
return () => {
if (intervalRef.current) {
clearInterval(intervalRef.current);
}
};
}, []);
return <p>Count: {count}</p>;
}
useReducer - État complexe
Pour les états complexes avec plusieurs sous-valeurs, useReducer est souvent plus adapté que useState :
type State = {
loading: boolean;
error: string | null;
data: User | null;
};
type Action =
| { type: 'FETCH_START' }
| { type: 'FETCH_SUCCESS'; payload: User }
| { type: 'FETCH_ERROR'; payload: string };
function reducer(state: State, action: Action): State {
switch (action.type) {
case 'FETCH_START':
return { ...state, loading: true, error: null };
case 'FETCH_SUCCESS':
return { loading: false, error: null, data: action.payload };
case 'FETCH_ERROR':
return { loading: false, error: action.payload, data: null };
default:
return state;
}
}
function UserProfile({ userId }: { userId: string }) {
const [state, dispatch] = useReducer(reducer, {
loading: false,
error: null,
data: null,
});
// Utilisation avec dispatch...
}
Quand utiliser quoi ?
Voici un récapitulatif :
| Hook | Utilisation |
|---|---|
useCallback | Fonctions passées en props |
useMemo | Calculs coûteux |
useRef | DOM ou valeurs persistantes |
useReducer | États complexes |
Bonnes pratiques
Pour résumer les bonnes pratiques :
- Mesurez avant d'optimiser - Utilisez React DevTools Profiler
- Évitez l'optimisation prématurée - La lisibilité prime
- Dépendances correctes - Incluez toutes les valeurs utilisées
- Custom hooks - Extrayez la logique réutilisable
Conclusion
Les hooks avancés de React sont des outils puissants pour optimiser vos applications. Utilisez-les judicieusement en vous concentrant sur les cas où ils apportent une réelle valeur ajoutée.
Commentaires
Les commentaires sont gérés via GitHub Discussions. En cliquant sur "Accepter", vous autorisez le chargement de contenu externe depuis GitHub.
Vos données seront traitées selon la politique de confidentialité de GitHub.