Svelte 5 traz melhorias internas – ou seja, componentes funcionais e adoção de sinais – mas, fora isso, é uma atualização principalmente incremental. A única exceção é o novo recurso Runas, que apresenta uma série de ideias para lidar com a reatividade de uma forma mais modular, sucinta e refinada.

Neste artigo, você terá uma introdução prática às principais runas que acompanham o Svelte 5: $state(), $derived(), $props(), $inspectI()e $efeito().

Runas em Svelte

À primeira vista, pode parecer que o novo recurso de runas adiciona complexidade ao trabalho com Svelte. Na verdade, essa ideia oferece uma abordagem mais simples para fazer muitas coisas que você provavelmente já faz. O termo runa refere-se a um glifo mágico ou uma letra alfabética com poderes misteriosos. No Svelte, as runas são tokens especiais que dizem ao compilador Svelte para trabalhar nos bastidores de maneiras específicas para fazer as coisas acontecerem.

Uma runa fornece uma sintaxe simples para dizer ao mecanismo Svelte para fazer um trabalho específico e útil, como gerenciar estado e expor propriedades de componentes.

As principais runas introduzidas no Svelte 5 são:

  • $state()
  • $derived()
  • $effect()
  • $props()
  • $inspect()

Como você pode ver, uma runa é uma função prefixada com um cifrão. Como desenvolvedor, você usa essas funções especiais quase exatamente como faria com qualquer outra função. O motor Svelte então se encarrega de implementar a ação pretendida da runa para você nos bastidores.

$estado()

Vamos começar olhando $state(), que é a runa que você provavelmente usará mais. Num sentido (muito) vago, o $state rune faz algo logicamente semelhante ao React useState() hook, fornecendo uma maneira funcional de lidar com o estado reativo.

Vamos considerar um exemplo simples. Veja como você criaria uma entrada e exibiria seu valor no Svelte 4, sem runas:


<script>
  let text = "Default";
</script>

<input type="text" bind:value={text}/>
Text: {text}

E agora, aqui está a mesma ação com o $state runa:


<script>
	let text = $state("Default")
</script>

<input type="text" bind:value={text}/>
Text: {text}

Em ambas as amostras, temos uma variável de estado simples (text) e use-o para direcionar uma entrada de texto que será exibida na tela. Este é um código Svelte típico, especialmente o bind:value={text} sintaxe, que oferece uma maneira simples de vincular bidirecionalmente a uma entrada.

A única mudança aqui é que, em vez de declarar uma variável normal com let text = "Default"nós a declaramos como uma runa de estado: let text = $state("Default"). O "Default" nós passamos para $state é o valor inicial.

Observe que o bind:value call não precisa mudar: Svelte sabe como usar uma runa nesse contexto. Em geral, o state rune a referência atua corretamente em qualquer lugar em que uma variável funcionaria.

Embora esta seja uma pequena mudança, há um benefício óbvio na clareza. É legal que o compilador Svelte perceba magicamente que let count = 0 deve ser reativo quando estiver no topo de um componente. Mas à medida que a base de código cresce, esse recurso fica um pouco ofuscante, pois fica difícil dizer quais variáveis ​​são reativas. O $state runa elimina esse problema.

Outro benefício é que $state pode aparecer em qualquer lugar, não apenas no nível superior dos seus componentes. Então, digamos que queremos uma função de fábrica que crie estados de texto para uso em entradas arbitrárias. Aqui está um exemplo simples:


<script>
	let makeText = function(def){
		let myText = $state(def);
		return { 
			get text() { return myText },
			set text(text) { myText = text },
		}
	}
	let text = makeText("test");
</script>

<input type="text" bind:value={text.text}/>
Text: {text.text}

Embora o exemplo seja inventado, a questão é que $state() A declaração cria um estado reativo funcional de dentro de um escopo diferente – algo que requer contorções na antiga sintaxe do Svelte. Observe também que, neste caso, fornecemos um getter e um setter para a variável text; isso ocorre porque o bind:value call é uma ligação bidirecional que requer acesso de leitura e gravação ao objeto de estado.

Outra propriedade interessante do $state() rune é que ele é automaticamente conectado aos membros de um objeto:


<script>
	let valueObject = new class { 
		text = $state('I am a test')
		num = $state(42)
	};
</script>

<input type="text" bind:value={valueObject.text}/>
<input type="number" bind:value={valueObject.num}/>
<br>
Text: {valueObject.text}
<br>
Number: {valueObject.num}

A essência deste trecho é que o text e num propriedades do valueObject class são automaticamente vinculadas de maneira adequada às entradas, sem declarar explicitamente os getters e setters. Svelte fornece automaticamente os getters e setters que o objeto precisa para acessar as propriedades do valueObject aula.

$derivado()

No passado, você poderia criar uma propriedade derivada usando o $: sintaxe em Svelte. Isso tinha algumas limitações, incluindo a possibilidade de os valores ficarem obsoletos porque o mecanismo só atualizava o valor calculado quando o componente era atualizado. Svelte 5 substitui o $: sintaxe com $derived()que mantém o valor calculado sempre sincronizado.

Aqui está um exemplo de uso $derived para combinar strings de entradas de texto:


<script>
	let greeting = $state("Hello there");
	let name = $state("User");
	let sentence = $derived(greeting + " " + name);
</script>

<input type="text" bind:value={greeting}/>
<input type="text" bind:value={name}/>
<br>
Text: {sentence }

O que estamos fazendo aqui é usar a variável sentença como runa derivada. É derivado das runas de estado de saudação e nome. Portanto, uma runa derivada combina os estados das variáveis ​​de estado.

Usando $derived(greeting + “ “ + name) garante que sempre que a saudação ou o nome forem alterados, a variável da frase refletirá essas alterações.

$efeito()

$effect é uma runa que funciona de forma semelhante ao efeito useState() do React. É usado para causar efeitos fora do motor reativo. Aqui está um exemplo dos documentos do Svelte:


$effect(() => {
  // runs when the component is mounted, and again
  // whenever `count` or `doubled` change,
  // after the DOM has been updated
  console.log({ count, doubled });

  return () => {
   // if a callback is provided, it will run
   // a) immediately before the effect re-runs
   // b) when the component is destroyed
	console.log('cleanup');
  };
});

O objetivo deste código é executar o log quando o componente for montado pela primeira vez e, em seguida, sempre que as variáveis ​​dependentes count e doubled são modificados. O valor de retorno opcional permite fazer qualquer limpeza necessária antes da execução do efeito ou quando o componente for desmontado.

$ adereços()

$props() é a nova maneira de declarar e consumir propriedades de componentes no Svelte. Isso abrange alguns casos de uso, especialmente a exportação de variáveis ​​no nível superior de componentes com let. Um exemplo vale mais que mil palavras e, em geral, o novo $props a sintaxe é limpa e óbvia:


// main.svelte
<script>
  import Component2 from './Component2.svelte';
</script>
<Component2>
</Component2>
<Component2 prop2 = "test">
</Component2>

// Component2.svelte
<script>
let { prop1 = "foo", prop2} = $props();
</script>
{prop1}
<br>
{prop2}

//outputs:
foo
foo
test

Aqui o main.svelte componente está importando Component2 e demonstrando como modificar os adereços por meio de propriedades na marcação. Notar que Component2 pode declarar valores padrão como prop1 = “foo”.

$inspecionar()

A última runa que veremos é $inspect. Este é um tipo de instrução de log reativa do console:


<script>
	let count = $state(0);
	let message = $state('hello');

	$inspect(count, message); // will console.log when `count` or `message` change
</script>

<button onclick={() => count++}>Increment</button>
<input bind:value={message} />

Neste exemplo (retirado da documentação do Svelte), o objetivo é emitir uma instrução de registro sempre que a contagem de variáveis ​​de mensagem for alterada. Em essência, ele oferece uma maneira simples de fazer logon no console de forma reativa, em resposta a atualizações de variáveis.

Conclusão

O efeito geral das runas é simplificar a API Svelte para desenvolvedores. Levará algum tempo para se ajustar à nova sintaxe e migrar o código existente, mas, em geral, a nova abordagem é realmente mais fácil. Se houver uma exceção, é o $effect() runa, que requer um pouco mais de reflexão antes de ser usada para substituir abordagens existentes. A elegância de $state(), $derived()e $props() mais do que compensar $effect()complexidade. Resumindo, o novo recurso Runas é uma ideia nova e bem-vinda em reatividade.