Skip to main content
基本 Svelte
介绍
反应性
属性
逻辑
事件
绑定
类和样式
动作
转换
高级 Svelte
高级反应性
重用内容
运动
高级绑定
高级转换
上下文 API
特殊元素
<script module>
后续步骤
基本 SvelteKit
介绍
路由
加载数据
标题和 cookie
共享模块
表单
API 路由
$app/state
错误和重定向
高级 SvelteKit
钩子
页面选项
链接选项
高级路由
高级加载
环境变量
结论

到目前为止,我们已经讨论了状态方面的反应性。但这只是等式的一半 - 状态只有在某些东西对其做出反应时才会产生反应,否则它只是一个闪闪发光的变量。

¥So far we’ve talked about reactivity in terms of state. But that’s only half of the equation — state is only reactive if something is reacting to it, otherwise it’s just a sparkling variable.

做出反应的东西称为效果。你已经遇到了效果 - Svelte 代表你创建的效果,用于响应状态更改来更新 DOM - 但你也可以使用 $effect 符文创建自己的效果。

¥The thing that reacts is called an effect. You’ve already encountered effects — the ones that Svelte creates on your behalf to update the DOM in response to state changes — but you can also create your own with the $effect rune.

大多数情况下,你不应该这样做。最好将 $effect 视为一个逃生出口,而不是经常使用的东西。例如,如果你可以将副作用放在 event handler 中,那几乎总是更好的选择。

假设我们想使用 setInterval 来跟踪组件的安装时间。创建效果:

¥Let’s say we want to use setInterval to keep track of how long the component has been mounted. Create the effect:

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

	$effect(() => {
		setInterval(() => {
			elapsed += 1;
		}, interval);
	});
</script>
<script lang="ts">
	let elapsed = $state(0);
	let interval = $state(1000);

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

单击 ‘加速’ 按钮几次,注意 elapsed 的上升速度更快,因为每次 interval 变小时,我们都会调用 setInterval

¥Click the ‘speed up’ button a few times and notice that elapsed ticks up faster, because we’re calling setInterval each time interval gets smaller.

如果我们然后单击 ‘减速’ 按钮...嗯,它不起作用。这是因为我们在效果更新时没有清除旧间隔。我们可以通过返回清理函数来解决这个问题:

¥If we then click the ‘slow down’ button... well, it doesn’t work. That’s because we’re not clearing out the old intervals when the effect updates. We can fix that by returning a cleanup function:

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

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

interval 更改时,以及当组件被销毁时,在效果函数重新运行之前立即调用清理函数。

¥The cleanup function is called immediately before the effect function re-runs when interval changes, and also when the component is destroyed.

如果效果函数在运行时没有读取任何状态,它将只在组件挂载时运行一次。

¥If the effect function doesn’t read any state when it runs, it will only run once, when the component mounts.

服务器端渲染期间不会运行效果。

上一页 下一页
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>