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
- Identifique a fonte de dados – No React, você provavelmente tem
const data = useMyFetch(url). No Solid, substitua isso por um memo que retorna a promise:const data = createMemo(() => fetch(url).then(r => r.json())). - Envolva o componente de nível superior – Se o componente renderizar antes da promise ser resolvida, envolva-o com
<Loading fallback={<Spinner/>}>…</Loading>. O fallback aparece apenas na primeira montagem. - Substitua os spinners de cada refetch – Onde você anteriormente alternava uma flag de carregamento, agora leia
isPending(data). Use esse booleano para renderizar um indicador sutil enquanto a UI existente permanece na tela. - Converta atualizações otimistas – Se você tinha
setState(prev => ({...prev, optimisticValue}))seguido por uma chamada assíncrona, reescreva comoconst update = action(function* (newValue) { state = newValue; const server = yield fetch(...); state = reconcile(server); });. O generator cede o controle até que o servidor responda e, em seguida, atualiza automaticamente o grafo reativo. - Lide com múltiplas partes assíncronas – Aninhe limites
<Loading>conforme necessário e, em seguida, adicione um wrapper<Reveal>para decidir se eles aparecem juntos ou um após o outro. Isso substitui padrões onde desenvolvedores React escalonavam múltiplos componentes<Suspense>com verificações de estado complexas. - Teste o fluxo – Como o Solid não realiza re-renderizações na resolução da promise, verifique se as atualizações de UI ainda ocorrem onde você espera. O grafo reativo propaga as mudanças automaticamente; não há necessidade de chamadas extras de
useEffect.
O que ainda está em transição
A API assíncrona do Solid 2.0 está atualmente em beta. Nomes como <Loading> e action podem mudar antes do lançamento estável, e a documentação ainda está evoluindo. A ideia central — tratar promises como valores reativos — permanece inalterada, mas os primeiros usuários devem esperar pequenas mudanças de quebra (breaking changes) à medida que a biblioteca se estabiliza.
Quem será beneficiado
- Equipes de React com intensa busca de dados – A redução da necessidade de bibliotecas de estado externas e o padrão integrado stale-while-revalidate podem diminuir o tamanho do bundle e simplificar as bases de código.
- Apps focados em performance – Ao evitar re-renderizações completas de componentes em cada fetch, o Solid entrega atualizações visuais mais suaves, especialmente em dispositivos de entrada.
- Desenvolvedores cansados do “flash de spinner” – O comportamento de “apenas no primeiro carregamento” do limite
<Loading>elimina o incômodo comum de um spinner piscando sobre um conteúdo que já está visível.
Possíveis desvantagens
- Status de beta – Até que a API se estabilize, projetos de longo prazo podem precisar planejar o esforço de migração posteriormente.
O que observar a seguir
Fique de olho no changelog oficial para qualquer renomeação de <Loading> ou action.
Resumo: O SolidJS 2.0 permite que você trate promises como valores reativos de primeira classe, mantendo a UI estável enquanto os dados são atualizados e removendo a necessidade de um conjunto de hooks no estilo React. Para equipes prontas para ir além do modelo centrado em re-renderização, o caminho de migração é claro, o ganho de performance é tangível e o único risco real é a incerteza habitual de uma fase beta.
