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
- Datenquelle identifizieren – In React haben Sie wahrscheinlich
const data = useMyFetch(url). Ersetzen Sie dies in Solid durch ein Memo, das das Promise zurückgibt:const data = createMemo(() => fetch(url).then(r => r.json())). - Die oberste Komponente umschließen – Falls die Komponente gerendert wird, bevor das Promise aufgelöst wird, umschließen Sie sie mit
<Loading fallback={<Spinner/>}>…</Loading>. Das Fallback erscheint nur beim ersten Mount. - Spinner bei jedem Refetch ersetzen – Wo Sie zuvor ein Loading-Flag umgeschaltet haben, lesen Sie nun
isPending(data). Verwenden Sie diesen Boolean, um einen dezenten Indikator anzuzeigen, während die bestehende UI auf dem Bildschirm bleibt. - Optimistische Updates konvertieren – Wenn Sie
setState(prev => ({...prev, optimisticValue}))gefolgt von einem asynchronen Aufruf hatten, schreiben Sie dies um alsconst update = action(function* (newValue) { state = newValue; const server = yield fetch(...); state = reconcile(server); });. Der Generator gibt die Kontrolle ab, bis der Server antwortet, und aktualisiert dann automatisch den reaktiven Graphen. - Mehrere asynchrone Teile handhaben – Verschachteln Sie
<Loading>-Grenzen nach Bedarf und fügen Sie dann einen<Reveal>-Wrapper hinzu, um zu entscheiden, ob sie gemeinsam oder nacheinander erscheinen. Dies ersetzt Muster, bei denen React-Entwickler mehrere<Suspense>-Komponenten mit komplexen State-Prüfungen gestaffelt haben. - Den Ablauf testen – Da Solid bei der Auflösung eines Promises nicht neu rendert, vergewissern Sie sich, dass UI-Updates dort stattfinden, wo Sie sie erwarten. Der reaktive Graph propagiert Änderungen automatisch; zusätzliche
useEffect-Aufrufe sind nicht erforderlich.
Was sich noch im Wandel befindet
Die asynchrone API von Solid 2.0 befindet sich derzeit in der Beta-Phase. Namen wie <Loading> und action können sich vor der stabilen Version noch ändern, und die Dokumentation entwickelt sich ständig weiter. Die Kernidee – Promises als reaktive Werte zu behandeln – bleibt unverändert, aber Early Adopter sollten mit geringfügigen Breaking Changes rechnen, während sich die Bibliothek stabilisiert.
Wer davon profitiert
- React-Teams mit intensivem Data Fetching – Der verringerte Bedarf an externen State-Libraries und das integrierte stale-while-revalidate-Pattern können die Bundle-Größe verringern und Codebasen vereinfachen.
- Performance-orientierte Apps – Durch das Vermeiden vollständiger Component-Re-Renders bei jedem Fetch liefert Solid flüssigere visuelle Updates, insbesondere auf Low-End-Geräten.
- Entwickler, die das „Aufblitzen von Spinnern“ satt haben – Das „First-Load-Only“-Verhalten der
<Loading>-Boundary eliminiert die häufige Unannehmlichkeit eines Spinners, der über Inhalten aufblitzt, die bereits sichtbar sind.
Mögliche Nachteile
- Beta-Status – Bis die API stabil ist, müssen Langzeitprojekte möglicherweise später Migrationsaufwand einplanen.
Worauf man als Nächstes achten sollte
Behalten Sie das offizielle Changelog im Auge, falls <Loading> oder action umbenannt werden.
Fazit: SolidJS 2.0 ermöglicht es Ihnen, Promises als erstklassige reaktive Werte zu behandeln, wodurch die UI stabil bleibt, während Daten aktualisiert werden, und der Bedarf an einer Reihe von React-typischen Hooks entfällt. Für Teams, die bereit sind, das re-render-zentrierte Modell zu verlassen, ist der Migrationspfad klar, der Performance-Vorteil greifbar und das einzige echte Risiko die übliche Unsicherheit einer Beta-Phase.
