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
- Xác định nguồn dữ liệu – Trong React, có thể bạn đang dùng
const data = useMyFetch(url). Trong Solid, hãy thay thế nó bằng một memo trả về promise:const data = createMemo(() => fetch(url).then(r => r.json())). - Bọc component cấp cao nhất – Nếu component được render trước khi promise được giải quyết, hãy bao quanh nó bằng
<Loading fallback={<Spinner/>}>…</Loading>. Phần fallback chỉ xuất hiện trong lần mount đầu tiên. - Thay thế các spinner khi refetch – Thay vì bật/tắt một flag loading như trước, giờ hãy đọc
isPending(data). Sử dụng giá trị boolean đó để hiển thị một chỉ báo tinh tế trong khi giao diện hiện tại vẫn được giữ trên màn hình. - Chuyển đổi các cập nhật lạc quan (optimistic updates) – Nếu bạn từng dùng
setState(prev => ({...prev, optimisticValue}))theo sau là một lời gọi async, hãy viết lại thànhconst update = action(function* (newValue) { state = newValue; const server = yield fetch(...); state = reconcile(server); });. Generator sẽ nhường quyền điều khiển cho đến khi server phản hồi, sau đó tự động cập nhật đồ thị phản ứng (reactive graph). - Xử lý nhiều phần bất đồng bộ – Lồng các ranh giới
<Loading>khi cần thiết, sau đó thêm một wrapper<Reveal>để quyết định xem chúng sẽ xuất hiện cùng lúc hay lần lượt. Điều này thay thế các pattern mà các nhà phát triển React thường phải sắp xếp nhiều component<Suspense>với các bước kiểm tra state phức tạp. - Kiểm tra luồng hoạt động – Vì Solid không re-render khi promise được giải quyết, hãy xác minh rằng UI vẫn cập nhật đúng nơi bạn mong đợi. Đồ thị phản ứng tự động lan truyền các thay đổi; không cần phải gọi thêm
useEffect.
Những gì vẫn đang thay đổi
API bất đồng bộ của Solid 2.0 hiện đang ở bản beta. Các tên gọi như <Loading> và action có thể thay đổi trước khi bản phát hành ổn định ra mắt, và tài liệu vẫn đang tiếp tục hoàn thiện. Ý tưởng cốt lõi—xử lý promise như các giá trị phản ứng—vẫn không đổi, nhưng những người dùng sớm nên chuẩn bị cho các thay đổi nhỏ gây lỗi (breaking changes) khi thư viện đi vào ổn định.
Ai sẽ được hưởng lợi
- Các nhóm React có nhu cầu fetch dữ liệu lớn – Việc giảm bớt nhu cầu sử dụng các thư viện state bên ngoài và pattern stale-while-revalidate tích hợp sẵn có thể giúp giảm kích thước bundle và đơn giản hóa codebase.
- Các ứng dụng chú trọng hiệu năng – Bằng cách tránh việc re-render toàn bộ component sau mỗi lần fetch, Solid mang lại các cập nhật hình ảnh mượt mà hơn, đặc biệt là trên các thiết bị cấu hình thấp.
- Các nhà phát triển mệt mỏi với tình trạng “nhấp nháy spinner” – Hành vi “chỉ tải lần đầu” của ranh giới
<Loading>giúp loại bỏ sự khó chịu thường gặp khi spinner nhấp nháy đè lên nội dung vốn đã hiển thị.
Những hạn chế có thể gặp
- Trạng thái Beta – Cho đến khi API ổn định, các dự án dài hạn có thể cần dự trù ngân sách cho việc di chuyển (migration) sau này.
Điều cần theo dõi tiếp theo
Hãy theo dõi changelog chính thức để biết bất kỳ sự thay đổi tên gọi nào của <Loading> hoặc action.
Tóm lại: SolidJS 2.0 cho phép bạn xử lý promise như các giá trị phản ứng hạng nhất, giữ cho UI ổn định trong khi dữ liệu được làm mới và loại bỏ nhu cầu về một loạt các hook kiểu React. Đối với các nhóm đã sẵn sàng vượt qua mô hình lấy re-render làm trung tâm, lộ trình di chuyển là rõ ràng, lợi ích về hiệu năng là hữu hình, và rủi ro thực sự duy nhất chỉ là sự không chắc chắn thường thấy ở giai đoạn beta.
