跳到主要內容

到目前為止,我們已經從狀態的角度討論了響應性。但這只是等式的一半 —— 只有當有東西對其「響應」時,狀態才是響應式的,否則它只是一個閃閃發光的變數。

響應的事物稱為「效果」。你已經遇到過效果了 —— Svelte 代表你建立的效果,用於響應狀態更改更新 DOM —— 但你也可以使用 $effect rune 建立自己的效果。

大多數情況下,你不應該這麼做。$effect 最好被視為一種逃生通道,而不是頻繁使用的東西。例如,如果你可以將副作用放在事件處理器中,那幾乎總是更可取的。

假設我們想要使用 setInterval 來追蹤元件已掛載的時間。建立效果

App
<script>
	let elapsed = $state(0);
	let interval = $state(1000);

	$effect(() => {
		setInterval(() => {
			elapsed += 1;
		}, interval);
	});
</script>

多次點擊「加速」按鈕,並注意 elapsed 滴答聲更快,因為每次 interval 變小時我們都會呼叫 setInterval

如果我們接著點擊「減速」按鈕...嗯,它不起作用。那是因為當效果更新時,我們沒有清除舊的間隔。我們可以透過傳回一個清理函式來修正這個問題

App
$effect(() => {
	const id = setInterval(() => {
		elapsed += 1;
	}, interval);

	return () => {
		clearInterval(id);
	};
});

interval 變更時,清理函式會在效果函式重新執行之前立即呼叫,也會在元件被銷毀時呼叫。

如果效果函式在執行時沒有讀取任何狀態,它只會在元件掛載時執行一次。

效果不會在伺服器端渲染期間執行。

在 GitHub 上編輯此頁面

上一頁 下一頁
1
2
3
4
5
6
7
8
9
10
<script>
	let elapsed = $state(0);
	let interval = $state(1000);
</script>
 
<button onclick={() => interval /= 2}>speed up</button>
<button onclick={() => interval *= 2}>slow down</button>
 
<p>elapsed: {elapsed}</p>