O que é SolidJS?
SolidJS é uma biblioteca de UI declarativa que se parece com React, mas funciona de forma muito diferente. Ela utiliza JSX e componentes, porém não possui virtual DOM e não realiza re-renders. Em vez disso, ela utiliza reatividade de grão fino (fine-grained reactivity): os signals rastreiam quem os lê e, quando um valor muda, apenas as computações e os nós do DOM que dependem dele são atualizados.
O efeito prático é que a função de um componente Solid é executada exatamente uma vez. Tudo o que é reativo dentro dela é conectado durante essa execução e, depois, atualizado de forma cirúrgica. Quando você compreende esse conceito, tanto a performance quanto as regras do Solid passam a fazer sentido.
Signals
Um signal é um valor reativo criado com createSignal. Ele retorna um getter e um setter.
// Counter.jsx
import { createSignal } from "solid-js";
export function Counter() {
const [count, setCount] = createSignal(0);
return (
<button onClick={() => setCount((c) => c + 1)}>
Count: {count()}
</button>
);
}
Você lê um signal chamando-o: count(). Essa chamada é o que registra uma dependência. Passar uma função para o setter (setCount((c) => c + 1)) é a maneira segura de atualizar o valor com base no valor anterior.
Valores derivados com createMemo
createMemo calcula um valor a partir de outros signals e o armazena em cache. Ele é recalculado apenas quando uma dependência muda, e o resultado é compartilhado entre todos os leitores.
// cart.jsx
import { createSignal, createMemo } from "solid-js";
const [items, setItems] = createSignal([{ price: 10 }, { price: 20 }]);
const total = createMemo(() =>
items().reduce((sum, item) => sum + item.price, 0),
);
Para expressões simples em linha, você também pode usar uma função comum, mas createMemo evita a repetição de tarefas pesadas. Utilize-o quando a computação for custosa ou for lida em vários lugares.
Effects
createEffect executa um efeito colateral sempre que os signals que ele lê são alterados. Ele serve para sincronização com o mundo externo, não para computar valores.
// title.jsx
import { createEffect, createSignal } from "solid-js";
const [name, setName] = createSignal("Ada");
createEffect(() => {
document.title = `Hello, ${name()}`;
});
Effects são executados após a renderização e rastreiam suas dependências automaticamente. Use onCleanup para encerrar subscriptions, timers e requisições.
Componentes executam apenas uma vez
Esta é a regra que costuma confundir desenvolvedores React. Um componente Solid é executado apenas uma vez. Ele é uma função de configuração que cria vínculos reativos, e não uma função que é reexecutada quando o estado muda.
function Profile(props) {
// Do not destructure props — that breaks reactivity.
// Read them where you use them instead.
return <h1>{props.user.name}</h1>;
}
Como as props são getters reativos, leia-as onde você as utiliza (props.user.name) em vez de fazer a desestruturação. O mesmo se aplica aos signals: chame-os dentro do JSX ou dentro de um memo, e não apenas uma vez no topo do componente.
Componentes de fluxo de controle
O Solid utiliza componentes em vez de diretivas de template para condicionais e listas, o que mantém tudo em JavaScript e permite que o compilador otimize as atualizações.
// list.jsx
import { Show, For } from "solid-js";
<Show when={users().length > 0} fallback={<p>No users yet.</p>}>
<ul>
<For each={users()}>{(user) => <li>{user.name}</li>}</For>
</ul>
</Show>
O Show renderiza seu fallback quando a condição é falsa, e o For utiliza chaves por referência para que possa mover nós do DOM em vez de recriá-los. O Index está disponível quando você deseja utilizar chaves por índice.
Stores
Para objetos reativos aninhados, createStore fornece um proxy com atualizações baseadas em caminhos (path-based updates).
// store.jsx
import { createStore } from "solid-js/store";
const [user, setUser] = createStore({
name: "Ada",
address: { city: "London" },
});
setUser("address", "city", "Paris");
Apenas as partes da árvore que foram alteradas notificam seus dependentes, portanto, atualizar uma propriedade profunda não invalida leituras não relacionadas. Stores são a maneira recomendada de gerenciar estados estruturados.
Recursos e dados assíncronos
createResource envolve uma função assíncrona em um signal, fornecendo estados de carregamento e erro sem a necessidade de controle manual.
// user.jsx
import { createResource, Show } from "solid-js";
const [user] = createResource(() => fetch("/api/user").then((r) => r.json()));
<Show when={user()} fallback={<p>Loading…</p>}>
<h1>{user().name}</h1>
</Show>;
O recurso é executado novamente quando seu signal de origem muda e cancela tarefas obsoletas, o que o torna ideal para dados que dependem de parâmetros de rota ou entrada do usuário.
Roteamento e SolidStart
O Solid Router gerencia a navegação no lado do cliente, e o SolidStart é o meta-framework que adiciona roteamento baseado em arquivos, renderização no servidor e carregamento de dados — o equivalente ao Next.js para React ou SvelteKit para Svelte. Para qualquer projeto que vá além de um simples widget, comece com o SolidStart.
Melhores práticas
- Leia signals e props onde você os utiliza; nunca faça a desestruturação deles antecipadamente.
- Use
createMemopara valores derivados caros ou amplamente compartilhados. - Use
createEffectapenas para efeitos colaterais (side effects) e faça a limpeza comonCleanup. - Prefira
createStorepara estados aninhados. - Use
ShoweForem vez de condicionais manuais e.map. - Mantenha os componentes como funções de setup e evite depender da re-execução.
- Utilize
createResourcepara dados assíncronos vinculados a fontes reativas.
Erros comuns
- Fazer a desestruturação de props ou valores de signals e quebrar a reatividade.
- Esperar que o corpo do componente seja executado novamente após uma mudança de estado.
- Usar um effect para computar um valor em vez de um memo.
- Esquecer o
onCleanupe causar vazamentos de subscriptions ou timers. - Usar
.mapno JSX em vez deFore perder as atualizações baseadas em chaves (keyed updates). - Assumir que as regras do React se aplicam e tentar usar hooks que não existem.
Próximos passos
O Solid valoriza a compreensão acima da memorização. Compare o modelo dele com o do React, Vue e Svelte, reforce seus conhecimentos em JavaScript e TypeScript, e utilize o Vite para o build. Depois, construa um pequeno app reativo e observe quão pouca coisa é re-executada.