0Pricing
Angular Academy · 课时

效果与副作用

使用效果响应信号变化。

效果与副作用 是 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 localStorage

Effect 不返回值

如果您需要派生值,请使用 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 runs

Effect 会自动清理

在组件中创建的 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 反馈 — 无需本地设置。

此课程中的所有课时

  1. 计算信号
  2. 效果与副作用
  3. 效果清理与生命周期
  4. linkedSignal 与高级模式
← 返回 Angular Academy