SolidJS 2.0 ships with a native async-data model that lets a component treat a promise like any other reactive value, and it does so without the cascade of re-renders that React developers see with Suspense and hooks. The change matters because it keeps UI on screen while data refreshes, cuts boilerplate, and offers a concrete path for React teams to move their data-fetching code over to Solid.
Why Solid’s async model feels different
In React, a component that needs data usually calls a hook (often a custom one) that returns a promise-like object, then wraps the UI in <Suspense> to show a fallback while the promise resolves. Every time the promise settles, React schedules a re-render; if the same component later refetches, the fallback can flash over content that is already visible.
Solid flips the script. A promise is simply a value that the reactive graph watches. When a computation reads that value, the graph pauses that read until the promise resolves, but the rest of the UI stays rendered. The first time a component mounts, a <Loading> boundary can display a fallback; after that, a refetch leaves the existing DOM untouched until the new data arrives. No explicit “await” inside the component, no createResource, no manual state toggles.
The core primitives
<Loading>boundary – Replaces React’s<Suspense>. It shows a fallback only on the initial load. After the first paint, a pending read does not replace the UI; the old content remains until the fresh value resolves. Pass anonprop to force a spinner on a specific refetch.<Reveal>component – Controls how multiple<Loading>boundaries appear together. Choose:- Sequential: boundaries reveal one after another in DOM order.
- Together: all reveal at once when every piece of data is ready.
- Natural: each reveals as soon as its own data lands.
isPendingsignal – Returnstruewhile a particular read is in flight. Use it to overlay a thin loading bar or subtle animation while the main content stays visible, giving you “stale-while-revalidate” for free.actiongenerator – Replaces React’s mutable-state updates. Anaction(function*…)can optimistically update the UI,yieldto wait for a server response, then reconcile the result when the promise resolves. The UI feels instant, and the reconciliation step is baked into the primitive.
How the pieces map to React concepts
| Feature | React approach | Solid 2.0 approach |
|---|---|---|
| Data fetching | use() (experimental) or third-party hooks; result wrapped in <Suspense> |
createMemo (or similar) that returns a promise; read directly in JSX |
| Loading UI | <Suspense> may re-trigger fallback on every refetch |
<Loading> only on first load; refetch keeps old UI |
| Refreshing | useTransition to defer UI updates |
isPending signals pending reads without UI swap |
| Mutations | useState/useReducer + async calls, often wrapped in custom actions |
action(function*…) with built-in optimistic handling |
The practical upshot is that Solid builds what React treats as separate hooks into the core reactivity engine.
A step-by-step migration guide
- Identifica la sorgente dei dati – In React probabilmente avrai
const data = useMyFetch(url). In Solid sostituiscilo con un memo che restituisce la promise:const data = createMemo(() => fetch(url).then(r => r.json())). - Avvolgi il componente di alto livello – Se il componente viene renderizzato prima che la promise si risolva, circondalo con
<Loading fallback={<Spinner/>}>…</Loading>. Il fallback appare solo al primo montaggio. - Sostituisci gli spinner per ogni refetch – Dove prima attivavi un flag di caricamento, ora leggi
isPending(data). Usa quel booleano per renderizzare un indicatore discreto mentre l'interfaccia esistente rimane sullo schermo. - Converti gli aggiornamenti ottimistici – Se avevi
setState(prev => ({...prev, optimisticValue}))seguito da una chiamata asincrona, riscrivilo comeconst update = action(function* (newValue) { state = newValue; const server = yield fetch(...); state = reconcile(server); });. Il generatore cede il controllo finché il server non risponde, quindi aggiorna automaticamente il grafo reattivo. - Gestisci più parti asincrone – Annida i confini
<Loading>secondo necessità, quindi aggiungi un wrapper<Reveal>per decidere se devono apparire insieme o uno dopo l'altro. Questo sostituisce i pattern in cui gli sviluppatori React alternavano più componenti<Suspense>con complessi controlli di stato. - Testa il flusso – Poiché Solid non effettua il re-render alla risoluzione della promise, verifica che gli aggiornamenti dell'interfaccia avvengano ancora dove previsto. Il grafo reattivo propaga le modifiche automaticamente; non c'è bisogno di chiamate
useEffectextra.
Cosa è ancora in fase di definizione
L'API asincrona di Solid 2.0 è attualmente in beta. Nomi come <Loading> e action potrebbero cambiare prima del rilascio stabile, e la documentazione è ancora in evoluzione. L'idea centrale — trattare le promise come valori reattivi — rimane invariata, ma gli utenti che adottano la tecnologia precocemente dovrebbero aspettarsi piccole breaking changes man mano che la libreria si stabilizza.
Chi ne trarrà vantaggio
- Team React con un intenso fetching di dati – La ridotta necessità di librerie di stato esterne e il pattern integrato stale-while-revalidate possono ridurre la dimensione del bundle e semplificare le basi di codice.
- App focalizzate sulle prestazioni – Evitando il re-render completo dei componenti a ogni fetch, Solid offre aggiornamenti visivi più fluidi, specialmente sui dispositivi di fascia bassa.
- Sviluppatori stanchi del "flash dello spinner" – Il comportamento "solo al primo caricamento" del confine
<Loading>elimina il comune fastidio di uno spinner che appare sopra contenuti già visibili.
Possibili svantaggi
- Stato beta – Finché l'API non si stabilizzerà, i progetti a lungo termine potrebbero dover prevedere uno sforzo di migrazione in seguito.
Cosa monitorare in seguito
Tieni d'occhio il changelog ufficiale per eventuali rinominazioni di <Loading> o action.
In sintesi: SolidJS 2.0 ti permette di trattare le promise come valori reattivi di prima classe, mantenendo l'interfaccia stabile durante l'aggiornamento dei dati e rimuovendo la necessità di una suite di hook in stile React. Per i team pronti a superare il modello centrato sul re-render, il percorso di migrazione è chiaro, il vantaggio in termini di prestazioni è tangibile e l'unico vero rischio è la consueta incertezza tipica della fase beta.
