Runes do Svelte 5: $state, $derived, $effect, $props | We.Inc
Cada rune do Svelte 5 com o código Svelte 4 que ela substitui: $state, $derived, $effect, $props e $bindable, além da nova sintaxe de eventos e snippets. Exemplos prontos para copiar.
Runes são as palavras-chave do compilador que o Svelte 5 usa para reatividade. $state declara uma variável reativa, $derived calcula um valor a partir de outro estado, $effect roda código depois que a página atualiza, $props lê as props do componente e $bindable marca uma prop à qual o componente pai pode fazer bind. Elas substituem o let reativo, o label $: e o export let do Svelte 4.
A sintaxe do Svelte 4 e a rune que a substitui
Função
Svelte 4
Svelte 5
Variável reativa
let count = 0
let count = $state(0)
Valor calculado
$: doubled = count * 2
let doubled = $derived(count * 2)
Efeito colateral
$: console.log(count)
$effect(() => console.log(count))
Props
export let name
let { name } = $props()
Prop com bind
export let value
let { value = $bindable() } = $props()
Event handler
on:click={fn}
onclick={fn}
Eventos de componente
createEventDispatcher
Props de callback
Slots
<slot />
{#snippet} and {@render}
Escolha uma rune para ver um componente Svelte 4 e a versão reescrita em Svelte 5. Cada par se comporta igual, então você pode migrar um arquivo por vez e conferir o resultado no caminho.
Selecione uma rune ou mudança de sintaxe nos botões.
Compare o código Svelte 4 à esquerda com o código Svelte 5 à direita.
Leia a nota com a regra que costuma pegar as pessoas de surpresa.
Copie a versão Svelte 5 para o seu componente.
Use $derived para tudo o que pode ser calculado. Deixe o $effect para conversar com coisas fora do Svelte, como o título do documento, um canvas ou um widget de terceiros.
Lembre que o $effect nunca roda durante a renderização no servidor, então é um lugar seguro para código que mexe em window ou document.
Use $state.raw com arrays grandes que você só substitui por inteiro. Ele dispensa o proxy profundo e só pode ser reatribuído.
Passe $state.snapshot(value) para bibliotecas que esperam um objeto simples em vez de um proxy.
As runes também funcionam em arquivos .svelte.js e .svelte.ts, o que permite compartilhar lógica reativa fora dos componentes.
Perguntas frequentes
Preciso reescrever o app inteiro para o Svelte 5?
Não. O Svelte 5 ainda aceita a sintaxe do Svelte 4, e componentes no estilo antigo e com runes podem conviver no mesmo app e usar uns aos outros, então você pode converter os arquivos um por um.
Por que o meu $effect não roda de novo?
O Svelte só rastreia o estado lido de forma síncrona dentro do efeito. Um valor lido depois de um await ou dentro de um callback de setTimeout não é uma dependência, então alterá-lo não faz nada.
Posso alterar um valor $derived?
Desde o Svelte 5.25 você pode reatribuir temporariamente um valor derivado, o que ajuda em atualizações otimistas, a menos que ele seja declarado com const. Ele é recalculado quando as dependências mudam. Versões anteriores tratam os derivados como somente leitura.
O que substituiu o createEventDispatcher?
Props de callback. O filho recebe uma função como onsave por meio de $props e a chama, e o pai passa o handler como qualquer outro atributo.
Como dou um id único a um campo de formulário?
Chame $props.id(), adicionado no Svelte 5.20. Ele retorna um id único para a instância do componente que é o mesmo no servidor e no navegador, então é seguro para for e aria-labelledby.
O $state é profundo por padrão
Envolver um array ou um objeto simples em $state dá a você um proxy profundamente reativo. Fazer push no array ou definir uma propriedade aninhada atualiza só as partes da página que a leem, sem precisar reatribuir o valor inteiro.
Campos de classe também podem ser estado: declare um campo com $state dentro de uma classe e o compilador o transforma em um par de getter e setter.
O $derived precisa continuar puro
A expressão dentro do $derived deve apenas calcular. O Svelte recusa mudanças de estado como count++ dentro dela. Para lógica mais longa, $derived.by recebe uma função cujo valor de retorno vira o valor derivado.
Os derivados são preguiçosos: o Svelte os marca como desatualizados quando uma dependência muda e os recalcula na próxima leitura, pulando o trabalho seguinte quando o resultado é o mesmo.
Timing e limpeza do $effect
Um efeito roda depois que o componente é montado e de novo depois que as dependências mudam, quando o DOM já foi atualizado. Retorne uma função do efeito para limpar timers ou listeners antes da próxima execução e quando o componente for destruído.
Se você precisa medir ou ajustar algo antes de o DOM mudar, como manter um histórico de chat rolado até o fim, use $effect.pre.
Compartilhando estado entre componentes
Uma store reativa em um arquivo .svelte.js
Uma variável $state reatribuída não pode ser exportada diretamente, então exporte um objeto e altere as propriedades dele.
$state
Um let simples não é mais reativo no modo runes. Envolva o valor inicial em $state e atualize-o como qualquer variável.
$derived
O label $: fazia dois trabalhos. Cálculos viram $derived; o Svelte os recalcula quando count muda.
$effect
Efeitos colaterais do $: passam para o $effect. Ele roda no navegador depois que o DOM atualiza, e o valor de retorno é a limpeza.
$props
Todas as props chegam por uma única desestruturação. Valores padrão, renomeações e rest props usam a sintaxe normal do JavaScript.
$bindable
Marque uma prop com $bindable para que o pai possa usar bind: nela. O código do pai continua igual.
Eventos
on:click vira o atributo onclick, e eventos personalizados viram props de callback em vez de createEventDispatcher.
Snippets
O snippet children substitui o slot padrão, e {@render} o posiciona. O ?. pula a renderização quando nenhum children foi passado.