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
- Identifica la fuente de datos – En React, probablemente tengas
const data = useMyFetch(url). En Solid, reemplaza eso con un memo que devuelva la promesa:const data = createMemo(() => fetch(url).then(r => r.json())). - Envuelve el componente de nivel superior – Si el componente se renderiza antes de que la promesa se resuelva, rodéalo con
<Loading fallback={<Spinner/>}>…</Loading>. El fallback aparece solo en el primer montaje. - Reemplaza los spinners por cada refetch – Donde antes alternabas un flag de carga, ahora lee
isPending(data). Usa ese booleano para renderizar un indicador sutil mientras la interfaz de usuario existente permanece en pantalla. - Convierte las actualizaciones optimistas – Si tenías
setState(prev => ({...prev, optimisticValue}))seguido de una llamada asíncrona, reescríbelo comoconst update = action(function* (newValue) { state = newValue; const server = yield fetch(...); state = reconcile(server); });. El generador cede el control hasta que el servidor responde, y luego actualiza automáticamente el grafo reactivo. - Gestiona múltiples piezas asíncronas – Anida límites de
<Loading>según sea necesario, y luego añade un envoltorio<Reveal>para decidir si aparecen juntos o uno tras otro. Esto reemplaza los patrones en los que los desarrolladores de React escalonaban múltiples componentes<Suspense>con comprobaciones de estado complejas. - Prueba el flujo – Debido a que Solid no vuelve a renderizar al resolverse la promesa, verifica que las actualizaciones de la interfaz de usuario sigan ocurriendo donde esperas. El grafo reactivo propaga los cambios automáticamente; no hay necesidad de llamadas adicionales a
useEffect.
Lo que aún está en evolución
La API asíncrona de Solid 2.0 está actualmente en fase beta. Nombres como <Loading> y action podrían cambiar antes del lanzamiento estable, y la documentación sigue evolucionando. La idea central —tratar las promesas como valores reactivos— permanece sin cambios, pero los adoptantes tempranos deben esperar cambios menores que rompan la compatibilidad a medida que la librería se asiente.
Quiénes se beneficiarán
- Equipos de React con una carga intensiva de datos – La menor necesidad de librerías de estado externas y el patrón integrado stale-while-revalidate pueden reducir el tamaño del bundle y simplificar las bases de código.
- Aplicaciones centradas en el rendimiento – Al evitar re-renderizados completos de componentes en cada fetch, Solid ofrece actualizaciones visuales más fluidas, especialmente en dispositivos de gama baja.
- Desarrolladores cansados del "flash of spinner" – El comportamiento de "solo en la primera carga" del límite
<Loading>elimina la molestia común de un spinner parpadeando sobre contenido que ya es visible.
Posibles inconvenientes
- Estado beta – Hasta que la API se estabilice, los proyectos a largo plazo podrían necesitar presupuestar esfuerzos de migración más adelante.
Qué observar a continuación
Mantente atento al changelog oficial para cualquier cambio de nombre en <Loading> o action.
En resumen: SolidJS 2.0 te permite tratar las promesas como valores reactivos de primera clase, manteniendo la interfaz de usuario estable mientras los datos se actualizan y eliminando la necesidad de un conjunto de hooks al estilo de React. Para los equipos listos para ir más allá del modelo centrado en el re-renderizado, la ruta de migración es clara, la ventaja en rendimiento es tangible y el único riesgo real es la incertidumbre habitual de la etapa beta.
