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
- منبع داده را شناسایی کنید – در React احتمالاً چنین دارید:
const data = useMyFetch(url). در Solid آن را با یک memo جایگزین کنید که پرومیس را برمیگرداند:const data = createMemo(() => fetch(url).then(r => r.json())). - کامپوننت سطح بالا را محصور کنید – اگر کامپوننت قبل از حل شدن (resolve) پرومیس رندر میشود، آن را با
<Loading fallback={<Spinner/>}>…</Loading>محصور کنید. حالت fallback فقط در اولین mount ظاهر میشود. - اسپینرهای مربوط به هر بار بازخوانی را جایگزین کنید – جایی که قبلاً یک پرچم loading را تغییر میدادید، اکنون
isPending(data)را بخوانید. از آن مقدار boolean برای نمایش یک نشانگر ظریف استفاده کنید، در حالی که رابط کاربری موجود روی صفحه باقی میماند. - آپدیتهای خوشبینانه (optimistic updates) را تبدیل کنید – اگر داشتید
setState(prev => ({...prev, optimisticValue}))که با یک فراخوانی async دنبال میشد، آن را به این صورت بازنویسی کنید:const update = action(function* (newValue) { state = newValue; const server = yield fetch(...); state = reconcile(server); });. ژنراتور کنترل را تا زمانی که سرور پاسخ دهد نگه میدارد، سپس به طور خودکار گراف واکنشپذیر (reactive graph) را بهروزرسانی میکند. - مدیریت چندین بخش async – مرزهای
<Loading>را در صورت نیاز در هم قرار دهید (nest کنید)، سپس یک wrapper از نوع<Reveal>اضافه کنید تا تصمیم بگیرید آیا آنها با هم ظاهر شوند یا یکی پس از دیگری. این جایگزین الگوهایی میشود که در آن توسعهدهندگان React چندین کامپوننت<Suspense>را با بررسیهای پیچیده وضعیت (state) به صورت مرحلهای قرار میدادند. - جریان را تست کنید – از آنجایی که Solid با حل شدن پرومیس دوباره رندر نمیشود، تأیید کنید که بهروزرسانیهای UI همچنان در جاهایی که انتظار دارید رخ میدهند. گراف واکنشپذیر تغییرات را به طور خودکار منتشر میکند؛ نیازی به فراخوانیهای اضافی
useEffectنیست.
آنچه هنوز در حال تغییر است
API ناهمگام (async) در Solid 2.0 در حال حاضر در مرحله بتا است. نامهایی مانند <Loading> و action ممکن است قبل از انتشار نسخه پایدار تغییر کنند و مستندات همچنان در حال تکامل هستند. ایده اصلی — یعنی برخورد با پرومیسها به عنوان مقادیر واکنشپذیر — بدون تغییر باقی میماند، اما کاربران اولیه باید با تثبیت کتابخانه، انتظار تغییرات ساختاری (breaking changes) جزئی را داشته باشند.
چه کسانی سود میبرند
- تیمهای React با دریافت دادههای سنگین – کاهش نیاز به کتابخانههای مدیریت وضعیت خارجی و الگوی داخلی stale-while-revalidate میتواند اندازه باندل را کاهش داده و پایگاههای کد را سادهتر کند.
- اپلیکیشنهای متمرکز بر عملکرد – با اجتناب از رندرهای مجدد کامل کامپوننت در هر بار fetch، Solid بهروزرسانیهای بصری روانتری را ارائه میدهد، بهویژه در دستگاههای ضعیف.
- توسعهدهندگانی که از «نمایش لحظهای اسپینر» خسته شدهاند – رفتار «فقط در اولین بارگذاری» در مرز
<Loading>، مزاحمت رایج نمایش لحظهای اسپینر روی محتوایی که از قبل قابل مشاهده است را از بین میبرد.
معایب احتمالی
- وضعیت بتا – تا زمانی که API تثبیت شود، پروژههای بلندمدت ممکن است نیاز داشته باشند بودجهای را برای تلاشهای مهاجرت در آینده در نظر بگیرند.
آنچه باید در ادامه دنبال کنید
تغییر نام احتمالی <Loading> یا action را در تغییرات رسمی (changelog) دنبال کنید.
خلاصه کلام: SolidJS 2.0 به شما اجازه میدهد با پرومیسها به عنوان مقادیر واکنشپذیر درجهاول برخورد کنید، رابط کاربری را هنگام بهروزرسانی دادهها ثابت نگه میدارد و نیاز به مجموعهای از هوکهای سبک React را از بین میبرد. برای تیمهایی که آمادهاند از مدلِ مبتنی بر رندر مجدد فراتر بروند، مسیر مهاجرت روشن است، مزیت عملکردی ملموس است و تنها ریسک واقعی، عدم قطعیت معمول در مرحله بتا است.
