效果与副作用
使用效果响应信号变化。
效果与副作用 是 CoddyKit 上的免费 Angular Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Angular Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Angular Academy 课程共包含 4 节课。
什么是 Effect
每当所读取的任意信号发生变化时,effect() 就会运行一个函数。与计算信号不同,Effect 用于执行副作用:记录日志、同步到 localStorage、调用 API、操作 DOM。
Effect 不会返回值。
创建 Effect
Effect 会立即运行一次,之后每当被跟踪的信号发生变化时再次运行。
import { signal, effect } from '@angular/core';
const count = signal(0);
effect(() => {
console.log('count is', count());
});
// logs "count is 0" immediately
count.set(5); // logs "count is 5"Effect 需要注入上下文
默认情况下,effect() 必须在注入上下文中创建——通常是在组件、指令或服务的构造函数或字段初始化器中创建。
import { Component, signal, effect } from '@angular/core';
@Component({ selector: 'app-x', template: '' })
export class XComponent {
user = signal('guest');
constructor() {
effect(() => console.log('user:', this.user()));
}
}自动跟踪依赖
与计算信号一样,Effect 会在运行时准确跟踪它们读取的信号。有条件的读取只有在实际执行到时才会被跟踪。
const enabled = signal(true);
const value = signal(10);
effect(() => {
if (enabled()) {
console.log(value());
}
});
// When enabled() is false, value is not a dependency将信号同步到 localStorage
Effect 的一个经典用例:每当状态发生变化时持久化状态。
const theme = signal('light');
effect(() => {
localStorage.setItem('theme', theme());
});
theme.set('dark'); // writes "dark" to localStorageEffect 不返回值
如果您需要派生值,请使用 computed()。Effect 用于执行不返回结果的操作;其结果本身就是副作用。
// WRONG: trying to derive state in an effect
// effect(() => this.total = this.a() + this.b());
// RIGHT: derive with computed
// total = computed(() => this.a() + this.b());在 Effect 中设置信号
默认情况下,Angular 禁止在 Effect 中写入信号,以防止循环。如果确实需要这样做,请传入 { allowSignalWrites: true }——但对于派生值,优先使用 computed。
effect(() => {
const v = source();
derived.set(v * 2);
}, { allowSignalWrites: true });
// Use sparingly; computed() is usually better使用 EffectRef 手动清理
effect() 会返回一个 EffectRef。调用 .destroy() 可在所有者销毁之前手动停止它。
import { effect, EffectRef } from '@angular/core';
const ref = effect(() => console.log(value()));
// later
ref.destroy(); // effect no longer runsEffect 会自动清理
在组件中创建的 Effect 会在组件销毁时自动销毁。您很少需要自行调用 .destroy()。
Effect 在渲染后运行
Effect 会被安排在变更检测之后运行,并按微任务进行批处理。多个同步的信号变化只会触发 Effect 一次。
const a = signal(0);
effect(() => console.log(a()));
a.set(1);
a.set(2);
a.set(3);
// Effect runs once with the final value 3 (batched)何时使用 effect,何时使用 computed
computed:从信号派生值(纯操作)。
effect:响应信号并执行外部操作(非纯操作)。
如果您发现自己要从 Effect 返回值,那么您可能真正需要的是计算信号。
快速检查
检验您对 Effect 的理解。
总结:Effect
effect() 会在其被跟踪的信号发生变化时运行一个函数,且仅用于副作用。
- 立即运行一次,之后在每次依赖发生变化时运行。
- 需要注入上下文。
- 会随所有者自动销毁;同时返回 EffectRef 以便手动控制。
- 使用 computed 进行派生,使用 effect 执行操作。
接下来:清理 Effect 内部的资源。
常见问题解答
「效果与副作用」课时是免费的吗?
是的 — 「效果与副作用」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Angular Academy 课程的其余内容,请升级到 CoddyKit PRO。 Angular Academy 课程共包含 4 节课。
「效果与副作用」这节课中我会学到什么?
使用效果响应信号变化。 你通过在浏览器中直接运行的动手代码来练习 Angular Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Angular Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Angular Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「效果与副作用」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Angular Academy 课中编写并运行代码吗?
能。每节 Angular Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。