LoginSignup
11
3

Svelte 5 に導入予定の新機能 Rune の紹介

Last updated at Posted at 2023-09-22

はじめに

2023年9月20日の夜、YouTube で以下の動画を見つけました。

Svelte 5 の新機能の紹介ということで、とても興奮しました!

Svelte 5 はまだリリース予定は決まってませんが、上記の動画のように導入予定の新機能が紹介されていたので簡単に紹介したいと思います。

ブログ

こちらのブログに上記の動画と同じことが書かれています。

しかも、既に日本語訳もされてます!

tomoam さんという方が翻訳してくれたみたいです。ありがとうございます!

Rune

読み方は "ルーン" です。

なんと既に Svelte 5 用の REPL サイトが構築されてます!

というわけで、こちら を参考に、どのような違いがあるのかを実際に動くものをお見せしたいと思います。

尚、サンプルアプリはシンプルな TODO アプリで、未完了の件数を remaining 関数を使ってリアクティブに表示しています。

image.png

まずは Rune を使わないバージョン

App.svelte
<script>
	let todos = [];

	function remaining(todos) {
		console.log('recalculating');
		return todos.filter(todo => !todo.done).length;
	}

	function addTodo(event) {
		if (event.key !== 'Enter') return;

		let done = false;
		let text = event.target.value;

		todos = [...todos, {
			done,
			text
		}];

		event.target.value = '';
	}
</script>

<input on:keydown={addTodo} />

{#each todos as todo}
	<div>
		<input bind:value={todo.text} />
		<input type="checkbox" bind:checked={todo.done} />
	</div>
{/each}

<p>{remaining(todos)} remaining</p>

追加した TODO アイテムのテキストボックスを編集するとコンソールログに recalculating が追加されます。つまり件数に影響のない変更をしているのにもかかわらず、再レンダリングが発生しちゃってます。

image.png

Rune を使うことで改善できます。

Rune を使うバージョン

App.svelte
<script>
-	let todos = [];
+	let todos = $state([]);

	function remaining(todos) {
		console.log('recalculating');
		return todos.filter(todo => !todo.done).length;
	}

	function addTodo(event) {
		if (event.key !== 'Enter') return;

-		let done = false;
-		let text = event.target.value;
+		let done = $state(false);
+		let text = $state(event.target.value);

		todos = [...todos, {
-			done,
-			text
+			get done() { return done },
+			set done(value) { done = value },
+			get text() { return text },
+			set text(value) { text = value }
		}];

		event.target.value = '';
	}
</script>

<input on:keydown={addTodo} />

{#each todos as todo}
	<div>
		<input bind:value={todo.text} />
		<input type="checkbox" bind:checked={todo.done} />
	</div>
{/each}

<p>{remaining(todos)} remaining</p>

image.png

様々な Rune

$state だけではなく、以下の様に様々な Rune があります。詳しくはブログや動画をご確認ください。

  • $state
  • $derived
  • $effect
  • $props

なんだか React っぽいですよね :laughing:

動機(の一部)

Rune を実装する動機としては以下もあるとのことです。

前記ブログより一部を抜粋します。

実際、アプリケーションが複雑になってくるにつれ、どの値がリアクティブでどの値がリアクティブでないのか判別するのが難しくなってくるのです。また、このヒューリスティックはコンポーネントのトップレベルにある let 宣言でのみ機能するため、混乱を招く可能性があります。コードの振る舞いが .svelte ファイル内と .js で異なっていると、コードのリファクタリングが難しくなります。例えば、何かを store にして複数の場所で使えるようにする必要がある場合などです。

私は個人で小規模な開発しかしてなかったのでピンとこなかったですが、なるほどな~と思いました。

まとめ

Svelte 5 で導入予定の Rune を簡単に紹介しました。詳しくはブログ等をご確認ください。

今まで同様シンプルな実装方法は維持しつつ、状況に応じて Rune を使ってよりきめ細かにリアクティブな実装ができるようになっています。また、Rune は .svelte ファイルだけではなく .js ファイルでも利用できるので応用の幅が広がりそうですね。

X(旧Twitter)では様々な反響があって面白いです。

私としては今までの書き方が好きだったので、それが維持される(であろう)ことが分かってちょっとホットしました。:blush:

11
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
3