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
- Kenal pasti sumber data – Dalam React, anda mungkin mempunyai
const data = useMyFetch(url). Dalam Solid, gantikan itu dengan memo yang mengembalikan promise:const data = createMemo(() => fetch(url).then(r => r.json())). - Balut komponen tahap teratas – Jika komponen dipaparkan sebelum promise selesai, kelilinginya dengan
<Loading fallback={<Spinner/>}>…</Loading>. Fallback hanya muncul pada pemasangan (mount) pertama. - Gantikan spinner bagi setiap pengambilan semula (refetch) – Di mana anda sebelum ini menukar flag pemuatan, kini baca
isPending(data). Gunakan boolean tersebut untuk memaparkan penunjuk halus sementara UI sedia ada kekal di skrin. - Tukar kemas kini optimistik (optimistic updates) – Jika anda mempunyai
setState(prev => ({...prev, optimisticValue}))diikuti dengan panggilan async, tulis semula sebagaiconst update = action(function* (newValue) { state = newValue; const server = yield fetch(...); state = reconcile(server); });. Generator menyerahkan kawalan sehingga pelayan memberi respons, kemudian mengemas kini graf reaktif secara automatik. - Kendalikan pelbagai bahagian async – Sarang (nest) sempadan
<Loading>mengikut keperluan, kemudian tambah pembungkus<Reveal>untuk menentukan sama ada ia muncul bersama-sama atau satu demi satu. Ini menggantikan corak di mana pembangun React menyusun komponen<Suspense>secara berturutan dengan semakan keadaan (state) yang kompleks. - Uji aliran – Oleh kerana Solid tidak melakukan render semula (re-render) apabila promise selesai, sahkan bahawa kemas kini UI masih berlaku di tempat yang anda jangkakan. Graf reaktif menyebarkan perubahan secara automatik; tiada keperluan untuk panggilan
useEffecttambahan.
Apa yang masih berubah-ubah
API async Solid 2.0 kini dalam fasa beta. Nama seperti <Loading> dan action mungkin berubah sebelum pelancaran stabil, dan dokumentasi masih berkembang. Idea terasnya—menganggap promise sebagai nilai reaktif—kekal tidak berubah, tetapi pengguna awal harus menjangkakan perubahan pecah (breaking changes) yang kecil apabila perpustakaan tersebut stabil.
Siapa yang akan mendapat manfaat
- Pasukan React dengan pengambilan data yang berat – Pengurangan keperluan untuk perpustakaan keadaan (state) luaran dan corak stale-while-revalidate terbina dalam dapat mengecilkan saiz bundle dan memudahkan pangkalan kod (codebase).
- Aplikasi berfokuskan prestasi – Dengan mengelakkan render semula komponen sepenuhnya pada setiap pengambilan data, Solid memberikan kemas kini visual yang lebih lancar, terutamanya pada peranti kelas rendah.
- Pembangun yang bosan dengan “flash of spinner” – Tingkah laku “hanya-muatan-pertama” sempadan
<Loading>menghapuskan gangguan biasa spinner yang berkelip di atas kandungan yang sudah pun kelihatan.
Kekurangan yang mungkin ada
- Status beta – Sehingga API stabil, projek jangka panjang mungkin perlu memperuntukkan usaha migrasi kemudian hari.
Apa yang perlu diperhatikan seterusnya
Perhatikan log perubahan (changelog) rasmi untuk sebarang penamaan semula <Loading> atau action.
Kesimpulannya: SolidJS 2.0 membolehkan anda menganggap promise sebagai nilai reaktif kelas pertama, mengekalkan UI yang stabil semasa data dikemas kini dan menghapuskan keperluan untuk rangkaian hook gaya React. Bagi pasukan yang bersedia untuk beralih melampaui model berpusatkan render semula, laluan migrasi adalah jelas, kelebihan prestasi adalah nyata, dan satu-satunya risiko sebenar ialah ketidakpastian biasa pada peringkat beta.
