Retour • 24/10/2024
Redux est mort. Utilise Zustand à la place...
Écris par Melvyn Malherbe le 24/10/2024
Redux est mort. Certes, il est encore beaucoup utilisé mais pour des nouveaux projets je le déconseille, surtout avec la nouvelle manière de faire.
La solution maintenant se compose en deux librairies puissantes :
Tanstack Query
qui permet de gérer le server-stateZustand
qui permet de gérer le client-state
Surtout que la majorité des états est maintenant stockée dans les server-components et n'a même plus lieu d'être dans le front-end.
Pourquoi Redux est mort ?
Redux a été la première librairie de state management vraiment populaire, s'il l'a été c'est car à l'époque le state en React n'était pas facile à gérer.
Redux a été pour des applications aux niveaux de Meta ADS
avec des milliers de menus, sous-menus et appels API de tous les côtés.
Le state dans Meta
est très compliqué à gérer et à maintenir.
Redux
permet d'ajouter des states, qui sont gérés en "flux" et qui permet à chaque partie de l'application de définir leur "reducer" qui permettra de communiquer avec les autres parties de l'application.
Redux
a été une révolution pour :
- gérer le state d'applications complexes
- travailler en équipe sans se marcher sur les pieds
Mais maintenant il est utilisé par des équipes de 3 développeurs sur des e-commerce, tu commences à voir le problème.
Les Server Components
La nouvelle philosophie de React qui pousse vers les Server Components
vient réduire énormément le besoin d'un state manager aussi complexe.
La majorité des données ne sont plus stockées côté client, quand tu vois ce code :
export default async function ProductPage() {
const products = await prisma.product.findMany();
return (
<ul>
{products.map((product) => (
<li key={product.id}>{product.name}</li>
))}
</ul>
);
}
Ici, dans ce Server Component
, il n'y a aucun client. Redux ne pourrait même pas exister. Il n'y a tout simplement pas de state, on vient juste afficher une liste de produits.
Mais à l'époque il aurait fallu faire un useEffect
pour récupérer les données et les stocker dans le state.
En résumé, les Server Components
changent beaucoup de paradigmes et réduisent encore plus le besoin d'un state manager aussi complexe.
Server-state
Cependant, parfois il faut être capable de venir stocker le Server State
, c'est-à-dire le state de notre serveur.
Pour ça, Tanstack Query
s'est imposé comme un leader incontournable.
Il va venir gérer un "cache" de toutes tes données et va te permettre de mettre à jour ton Server State
quand tu veux.
'use client';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { useState } from 'react';
export const ProductList = () => {
const queryClient = useQueryClient();
const {
data: products,
error,
isLoading,
} = useQuery({
queryKey: ['products'],
queryFn: async () => {
// get call
},
});
const mutation = useMutation({
mutationFn: async (newProduct) => {
// fetch call
},
onSuccess: () => {
queryClient.invalidateQueries(['products']);
},
});
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<div>
<ul>
{products.map((product) => (
<li key={product.id}>{product.name}</li>
))}
</ul>
<button onClick={handleAddProduct}>Add Product</button>
</div>
);
};
Ici, on peut facilement récupérer des données et les muter, c'est simple, efficace et fait pour ça.
Tanstack Query
nous permet de gérer tout le Server State qui dépend de données asynchrones pour fonctionner.
Mais parfois, il y a des choses client. Par exemple, l'état actuel d'une Sidebar.
Ici quand on parle de Server-state
ou Client-state
, il faut comprendre que tout
ici est stocké côté client. On parle plutôt des données qu'il contient. Le
Server-state
contient des données du Server
alors que le Client-state
contient des données du Client
.
Client-state
Pour le client State, le leader c'est Zustand
qui va te permettre de créer des stores, qui remplaceraient un useContext
placé dans le App.tsx
.
Tu peux créer facilement un store :
import { create } from 'zustand';
const useStore = create((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
}));
Et là, on peut facilement utiliser notre store :
import { useStore } from './store';
export const Counter = () => {
const { count, increment } = useStore();
return (
<div>
<p>Current count: {count}</p>
<button onClick={increment}>Increment</button>
</div>
);
};
Ce store, est accessible partout dans ton application, même en dehors de React :
import { useStore } from './store';
// Possible de l'utiliser en dehors de React
const increment = () => {
useStore.getState().increment();
};
Zustand
, contrairement à Redux
, a une approche "micro" des stores. Il n'y a pas de reducers, il n'y a pas de dispatch
et il n'y a pas d'action
.
On va plutôt créer plein de stores, dans une application tu pourrais avoir :
useSidebarStore
pour gérer l'état de la sidebaruseEditorStore
pour gérer l'état de l'éditeur- etc...
Un store = une fonctionnalité.
Pourquoi ne pas utiliser useContext
? Déjà car tu vas avoir plus de code. Mais aussi car Zustand
supporte les sélecteurs qui te permettent d'optimiser les renders.
Quand un contexte change, tous les composants qui le consomment sont re-rendus même ceux qui n'utilisent pas les données modifiées.
Alors qu'avec zustand
il est possible de sélectionner les données :
import { useStore } from './store';
export const CounterIncrement = () => {
const count = useStore((state) => state.increment);
return (
<div>
<button onClick={count}>Increment</button>
</div>
);
};
Ce composant ne sera jamais re-rendu car la méthode increment
ne va jamais changer (normalement).
Quand utiliser Redux
?
Redux
est mort dans la grande majorité des applications. Si ton application dépend beaucoup de données côté serveur :
- utilise les
Server Components
- utilise
Tanstack Query
Si ton application a besoin d'un peu de données côté client :
- utilise
Zustand
Mais dans le rare cas où tu crées une application aussi complexe que Meta ADS, ou un manager de tickets où énormément de données ont un rapport entre elles et que c'est un joyeux bordel... déjà bonne chance.
Mais aussi ici, dans ce rare cas qui représente 5% des applications, utilise Redux
.
Conclusion
Redux
est presque mort... enfin pour la majorité des applications. Je t'ai partagé mes conseils à toi de les suivre.
Tu peux apprendre à mieux utiliser React et Zustand dans ma formation BegiNReact :
Le meilleur moyen d'apprendre React !
Rejoins par développeurs, cette formation reçoit une note de 4.7 / 5 🚀
Reçois 12 leçons premium pour maîtriser React et faire partie des meilleurs
Tu pourrais vouloir aussi apprendre pourquoi tu n'as pas besoin de useCallback ou la différence entre une propre et un state en React.