Skip to main content
Svelte 基础
介绍
响应式
属性
逻辑
事件
绑定
类和样式
Actions
过渡动画
Svelte 进阶
高级响应性
复用内容
Motion
高级绑定
高级过渡效果
Context API
特殊元素
<script module>
后续步骤
SvelteKit 基础
介绍
路由
加载数据
请求头和 Cookie
共享模块
表单
API 路由
$app/state
错误和重定向
SvelteKit 进阶
钩子函数
页面选项
链接选项
高级路由
高级加载
环境变量
结论

到目前为止,我们讨论的响应性主要是从状态的角度。但这只是等式的一半 — 只有某些东西对状态做出响应,状态才是响应式的,否则它只是一个普通的变量。

响应状态的东西被称为effect。其实你已经遇到过 effect 了 — 就是 Svelte 替你创建的、响应状态变化而更新 DOM,这就是一个 effect — 但你也可以使用 $effect 符文创建自己的 effect。

大多数情况下,你不应该这样做。$effect 最好被视为一个应急方案,而不是频繁使用的东西。比如,如果你可以将副作用放在事件处理器中,那几乎总是更好的选择。

假设我们想使用 setInterval 来跟踪组件已挂载的时间。创建一个 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

如果我们点击”减速”按钮... 好吧,它不起作用。这是因为当 effect 更新时,我们没有清除旧的定时器。我们可以通过返回一个清理函数来解决这个问题:

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

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

interval 改变时,清理函数会在 effect 函数重新运行之前立即被调用,此外组件销毁时也会被调用。

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

Effects 不会在服务器端渲染期间运行。

在 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>