SolidJS 2.0 propose un modèle de données asynchrones natif qui permet à un composant de traiter une promesse comme n'importe quelle autre valeur réactive, et ce, sans la cascade de re-rendus que les développeurs React observent avec Suspense et les hooks. Ce changement est important car il maintient l'interface utilisateur à l'écran pendant le rafraîchissement des données, réduit le boilerplate et offre une voie concrète aux équipes React pour migrer leur code de récupération de données vers Solid.
Pourquoi le modèle asynchrone de Solid semble différent
Dans React, un composant qui a besoin de données appelle généralement un hook (souvent un hook personnalisé) qui renvoie un objet de type promesse, puis enveloppe l'interface utilisateur dans <Suspense> pour afficher un fallback pendant que la promesse se résout. Chaque fois que la promesse est résolue, React planifie un re-rendu ; si le même composant effectue plus tard un refetch, le fallback peut apparaître brièvement par-dessus le contenu déjà visible.
Solid change la donne. Une promesse est simplement une valeur que le graphe réactif surveille. Lorsqu'un calcul lit cette valeur, le graphe met cette lecture en pause jusqu'à ce que la promesse soit résolue, mais le reste de l'interface utilisateur reste rendu. La première fois qu'un composant est monté, une frontière <Loading> peut afficher un fallback ; après cela, un refetch laisse le DOM existant intact jusqu'à ce que les nouvelles données arrivent. Pas de "await" explicite à l'intérieur du composant, pas de createResource, pas de bascule d'état manuelle.
Les primitives de base
- Frontière
<Loading>– Remplace le<Suspense>de React. Elle n'affiche un fallback que lors du chargement initial. Après le premier rendu, une lecture en attente ne remplace pas l'interface utilisateur ; l'ancien contenu reste en place jusqu'à ce que la nouvelle valeur soit résolue. Passez une proponpour forcer l'affichage d'un spinner lors d'un refetch spécifique. - Composant
<Reveal>– Contrôle la manière dont plusieurs frontières<Loading>apparaissent ensemble. Choisissez :- Séquentiel : les frontières apparaissent l'une après l'autre selon l'ordre du DOM.
- Ensemble : toutes apparaissent en même temps lorsque chaque donnée est prête.
- Naturel : chacune apparaît dès que ses propres données sont arrivées.
- Signal
isPending– Renvoietruependant qu'une lecture particulière est en cours. Utilisez-le pour superposer une fine barre de chargement ou une animation subtile pendant que le contenu principal reste visible, vous offrant ainsi le "stale-while-revalidate" gratuitement. - Générateur
action– Remplace les mises à jour d'état mutable de React. Uneaction(function*…)peut mettre à jour l'interface de manière optimiste, utiliseryieldpour attendre une réponse du serveur, puis réconcilier le résultat lorsque la promesse est résolue. L'interface semble instantanée, et l'étape de réconciliation est intégrée à la primitive.
Correspondance des concepts avec React
| Fonctionnalité | Approche React | Approche Solid 2.0 |
|---|---|---|
| Récupération de données | use() (expérimental) ou hooks tiers ; résultat enveloppé dans <Suspense> |
createMemo (ou similaire) qui renvoie une promesse ; lecture directe dans le JSX |
| UI de chargement | <Suspense> peut déclencher à nouveau le fallback à chaque refetch |
<Loading> uniquement au premier chargement ; le refetch conserve l'ancienne UI |
| Rafraîchissement | useTransition pour différer les mises à jour de l'UI |
Les signaux isPending signalent les lectures en cours sans changer l'UI |
| Mutations | useState/useReducer + appels asynchrones, souvent enveloppés dans des actions personnalisées |
action(function*…) avec gestion optimiste intégrée |
Le résultat concret est que Solid intègre au moteur de réactivité de base ce que React traite comme des hooks distincts.
Guide de migration étape par étape
- Identifier la source de données – En React, vous avez probablement
const data = useMyFetch(url). Dans Solid, remplacez cela par un memo qui renvoie la promesse :const data = createMemo(() => fetch(url).then(r => r.json())). - Envelopper le composant de haut niveau – Si le composant est rendu avant la résolution de la promesse, entourez-le de
<Loading fallback={<Spinner/>}>…</Loading>. Le fallback n'apparaît que lors du premier montage. - Remplacer les spinners de rechargement – Là où vous basculiez auparavant un indicateur de chargement, lisez maintenant
isPending(data). Utilisez ce booléen pour afficher un indicateur subtil pendant que l'interface utilisateur existante reste à l'écran. - Convertir les mises à jour optimistes – Si vous aviez
setState(prev => ({...prev, optimisticValue}))suivi d'un appel asynchrone, réécrivez commeconst update = action(function* (newValue) { state = newValue; const server = yield fetch(...); state = reconcile(server); });. Le générateur cède le contrôle jusqu'à ce que le serveur réponde, puis met automatiquement à jour le graphe réactif. - Gérer plusieurs éléments asynchrones – Imbriquez les limites
<Loading>selon les besoins, puis ajoutez un wrapper<Reveal>pour décider s'ils apparaissent ensemble ou l'un après l'autre. Cela remplace les modèles où les développeurs React échelonnaient plusieurs composants<Suspense>avec des vérifications d'état complexes. - Tester le flux – Comme Solid ne re-rend pas lors de la résolution d'une promesse, vérifiez que les mises à jour de l'interface utilisateur se produisent toujours là où vous les attendez. Le graphe réactif propage les changements automatiquement ; il n'est pas nécessaire d'ajouter des appels
useEffectsupplémentaires.
Ce qui est encore en évolution
L'API asynchrone de Solid 2.0 est actuellement en version bêta. Des noms comme <Loading> et action pourraient changer avant la version stable, et la documentation continue d'évoluer. L'idée centrale — traiter les promesses comme des valeurs réactives — reste inchangée, mais les premiers utilisateurs doivent s'attendre à de légers changements de rupture à mesure que la bibliothèque se stabilise.
Qui peut en bénéficier
- Les équipes React avec un important chargement de données – La réduction du besoin de bibliothèques d'état externes et le modèle intégré stale-while-revalidate peuvent réduire la taille du bundle et simplifier les bases de code.
- Les applications axées sur la performance – En évitant les re-rendus complets des composants à chaque fetch, Solid offre des mises à jour visuelles plus fluides, en particulier sur les appareils d'entrée de gamme.
- Les développeurs fatigués du « flash de spinner » – Le comportement « premier chargement uniquement » de la limite
<Loading>élimine l'agacement courant d'un spinner qui clignote par-dessus un contenu déjà visible.
Inconvénients possibles
- Statut bêta – Jusqu'à ce que l'API se stabilise, les projets à long terme devront peut-être prévoir un effort de migration ultérieur.
À surveiller ensuite
Gardez un œil sur le changelog officiel pour tout renommage de <Loading> ou action.
En résumé : SolidJS 2.0 vous permet de traiter les promesses comme des valeurs réactives de premier ordre, maintenant l'interface utilisateur stable pendant le rafraîchissement des données et supprimant le besoin d'une suite de hooks de style React. Pour les équipes prêtes à dépasser le modèle centré sur le re-rendu, le chemin de migration est clair, le gain de performance est tangible, et le seul véritable risque est l'incertitude habituelle de la phase bêta.
