Dans toute application Web, la gestion des états de chargement et d'erreur est cruciale. L'affichage des états de chargement permet de tenir l'utilisateur informé, mais historiquement, cette gestion peut être fastidieuse à mettre en œuvre manuellement.
React Query simplifie grandement la gestion des états de chargement et des états globaux. En effet, React Query évite les requêtes redondantes, optimisant ainsi les performances de l'application.
Prenons un exemple de code qui implémente un état de chargement dans notre application.
Définissez un hook pour récupérer une liste d'utilisateurs :
export const useUsers = () => { const { data, isLoading } = useQuery<User[]>({ queryKey: ["users"], queryFn: async () => { const response = await fetch("https://jsonplaceholder.typicode.com/users"); await new Promise((resolve) => setTimeout(resolve, 2000)); return response.json(); }, }); return { users: data?.slice(0, 4) || [], isLoading, }; };
Ici, nous récupérons quatre utilisateurs avec useQuery. Nous ajoutons un délai de 2 secondes pour illustrer l'état de chargement. Nous renvoyons ensuite les données et un booléen pour l'état de chargement.
Côté composant, créons un composant nommé Exemple :
const Example = (): JSX.Element => { const { users, isLoading } = useUsers(); if (isLoading) { return <div>Loading...</div>; } return ( <div className="container"> <div className="user-action"> <h1>Users</h1> <div> <button>Add users</button> </div> </div> <UsersList users={users} /> </div> ); };
Dans ce composant, nous utilisons notre hook pour récupérer la liste des utilisateurs. Avant de restituer la vue, nous effectuons un "retour anticipé" avec un message de chargement, puis affichons le titre, le bouton et les utilisateurs.
Cependant, chaque appel réseau nécessite une gestion explicite de l'état de chargement. Si le code n'est pas factorisé, certains éléments de la vue peuvent être en attente d'affichage, comme le titre et l'action.
Voici une alternative pour éviter de bloquer la vue :
import "./App.css"; import UsersList from "./UsersList"; import { useUsers } from "./useUsers"; const Example = (): JSX.Element => { const { users, isLoading } = useUsers(); return ( <div className="container"> <div className="user-action"> <h1>Users</h1> <div> <button>Add users</button> </div> </div> {isLoading ? <div>Loading...</div> : <UsersList users={users} />} </div> ); };
Ici, nous utilisons le rendu conditionnel au lieu d'un "retour anticipé". Cette solution est moins lisible et plus difficile à maintenir dans des composants complexes.
La solution la plus ingénieuse consiste à créer un composant qui restitue notre message de chargement ou notre composant principal en fonction d'une variable.
type Props = PropsWithChildren<{ isLoading: boolean; }>; const LoadingWrapper = ({ children, isLoading }: Props): JSX.Element => { if (isLoading) { return <div>Loading...</div>; } return <>{children}</>; };
Utilisation dans notre composant
const Example = (): JSX.Element => { const { users, isLoading } = useUsers(); return ( <div className="container"> ... <LoadingWrapper isLoading={isLoading}> <UsersList users={users} /> </LoadingWrapper> </div> ); };
Cette factorisation centralise la logique de rendu conditionnel et unifie l'utilisation du chargement des messages, offrant un code plus propre et plus maintenable.
Mais maintenant, si je vous dis que ce composant que nous venons de créer est déjà intégré à React. Mieux encore, c'est magique ! Fini la gestion manuelle des états isLoading !
Avec Suspense de React (version React >= 16.6), tout devient plus simple et plus propre. Suspense permet de déclarer explicitement à React qu'un composant attend des données asynchrones, et React s'occupe de tout gérer pour nous.
Utilisons useSuspenseQuery pour gérer automatiquement l'état de chargement. Voici comment procéder :
Hook pour récupérer les utilisateurs
export const useUsersSuspense = () => { const { data } = useSuspenseQuery<User[]>( ... ); return { users: data?.slice(0, 4) || [], // Without the isLoading }; };
Maintenant, mettons à jour notre composant Exemple pour utiliser Suspense :
const UsersComponent = (): JSX.Element => { const { users } = useUsersSuspense(); return <UsersList users={users} />; }; const Example = (): JSX.Element => { return ( <div className="container"> <div className="user-action"> <h1>Users</h1> <div> <button>Add users</button> </div> </div> <Suspense fallback={<div>Loading...</div>}> <UsersComponent /> </Suspense> </div> ); };
Avec Suspense, nous centralisons la gestion de l'état de chargement en un seul endroit, rendant le code plus lisible et maintenable. La solution de secours Suspense s'affiche automatiquement tant que les données ne sont pas disponibles, éliminant ainsi le besoin de gérer manuellement les états isLoading.
De plus, Suspense encourage les équipes de développement à factoriser leur code. En utilisant des composants de chargement standardisés et des gestionnaires d'état asynchrones, les développeurs peuvent créer des modules réutilisables et cohérents, améliorant ainsi la qualité et la maintenabilité du code à long terme.
L'utilisation de Suspense et useSuspenseQuery révolutionne la gestion des états de chargement dans les applications React. Cette approche simplifie non seulement le code mais améliore également l'expérience utilisateur en garantissant un rendu fluide et cohérent. La transition de useQuery à useSuspenseQuery est une évolution naturelle pour des applications plus propres et plus efficaces.
De plus, l'intégration de Suspense encourage les équipes de développement à factoriser leur code. En conclusion, adopter Suspense et useSuspenseQuery n'est pas seulement une amélioration technique, mais aussi une étape vers des pratiques de développement plus saines et plus efficaces.
Ma Newsletter :D
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!