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 an on prop 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.
  • isPending signal – Returns true while 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.
  • action generator – Replaces React’s mutable-state updates. An action(function*…) can optimistically update the UI, yield to 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

  1. Identificeer de gegevensbron – In React heb je waarschijnlijk const data = useMyFetch(url). Vervang dit in Solid door een memo die de promise retourneert: const data = createMemo(() => fetch(url).then(r => r.json())).
  2. Omwikkel de top-level component – Als de component wordt gerenderd voordat de promise is opgelost, omwikkel deze dan met <Loading fallback={<Spinner/>}>…</Loading>. De fallback verschijnt alleen bij de eerste mount.
  3. Vervang spinners per refetch – Waar je voorheen een loading-flag omzette, lees je nu isPending(data). Gebruik die boolean om een subtiele indicator te renderen terwijl de bestaande UI op het scherm blijft staan.
  4. Converteer optimistic updates – Als je setState(prev => ({...prev, optimisticValue})) had gevolgd door een async call, herschrijf dit dan als const update = action(function* (newValue) { state = newValue; const server = yield fetch(...); state = reconcile(server); });. De generator geeft de controle vrij totdat de server reageert en werkt vervolgens automatisch de reactieve graaf bij.
  5. Behandel meerdere async onderdelen – Nest <Loading> boundaries indien nodig, en voeg dan een <Reveal> wrapper toe om te bepalen of ze samen of na elkaar verschijnen. Dit vervangt patronen waarbij React-ontwikkelaars meerdere <Suspense> componenten na elkaar lieten verschijnen met complexe state-checks.
  6. Test de flow – Omdat Solid niet opnieuw rendert bij het oplossen van een promise, controleer of UI-updates nog steeds plaatsvinden waar je ze verwacht. De reactieve graaf verspreidt wijzigingen automatisch; extra useEffect calls zijn niet nodig.

Wat nog in beweging is

De async API van Solid 2.0 bevindt zich momenteel in bèta. Namen zoals <Loading> en action kunnen veranderen voor de stabiele release, en de documentatie is nog volop in ontwikkeling. Het kernidee — het behandelen van promises als reactieve waarden — blijft ongewijzigd, maar vroege gebruikers moeten rekening houden met kleine breaking changes naarmate de library stabiliseert.

Wie profiteert hiervan

  • React-teams met intensieve data fetching – De verminderde behoefte aan externe state-libraries en het ingebouwde stale-while-revalidate-patroon kunnen de bundelgrootte verkleinen en codebases vereenvoudigen.
  • Performance-gerichte apps – Door volledige component re-renders bij elke fetch te vermijden, levert Solid soepelere visuele updates, vooral op apparaten met minder rekenkracht.
  • Ontwikkelaars die klaar zijn met de "flash of spinner" – Het 'first-load-only'-gedrag van de <Loading> boundary elimineert de bekende irritatie van een spinner die over content flitst die al zichtbaar is.

Mogelijke nadelen

  • Bèta-status – Totdat de API stabiliseert, moeten langetermijnprojecten mogelijk rekening houden met migratie-inspanningen in de toekomst.

Waar je op moet letten

Houd de officiële changelog in de gaten voor eventuele hernoemingen van <Loading> of action.

De kern: SolidJS 2.0 stelt je in staat om promises te behandelen als first-class reactieve waarden, waardoor de UI stabiel blijft terwijl gegevens worden ververst en de noodzaak voor een reeks React-stijl hooks vervalt. Voor teams die klaar zijn om verder te gaan dan het re-render-gecentreerde model, is het migratiepad duidelijk, is het voordeel in performance tastbaar en is het enige echte risico de gebruikelijke onzekerheid van de bètafase.