# $effect and When Not to Use It — Svelte / SvelteKit

Source: https://www.skillbyai.com/en/svelte/r-effect

> Side effects that sync with the outside world.

## Effects run after the DOM updates

`$effect(() => { ... })` runs after the component mounts and again after any state it read changes, once the DOM has been updated. It can return a **teardown** function that runs before the next run and when the component is destroyed. Effects **do not run during server-side rendering**. Use them to synchronise with external systems: a canvas, a third-party widget, a timer, `localStorage` or analytics. `$effect.pre` runs before DOM updates (for example to preserve scroll position). **Do not** use effects to compute state from other state; use `$derived`, which avoids extra update cycles. For event-driven work, put the logic in the event handler. `$inspect(value)` logs changes during development.

## A timer and a canvas

Teardown and dependency tracking.

```svelte
<script lang="ts">
  let size = $state(40);
  let color = $state('#ea580c');
  let canvas: HTMLCanvasElement;
  let elapsed = $state(0);

  // re-runs when size or color change (both are read inside)
  $effect(() => {
    const ctx = canvas.getContext('2d')!;
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = color;
    ctx.fillRect(0, 0, size, size);
  });

  // sets up once; teardown clears the interval on destroy
  $effect(() => {
    const id = setInterval(() => (elapsed += 1), 1000);
    return () => clearInterval(id);
  });

  // wrong: let double = $state(0); $effect(() => { double = size * 2; });
  let double = $derived(size * 2); // right
</script>

<canvas bind:this={canvas} width="200" height="200"></canvas>
<input type="range" min="10" max="200" bind:value={size} />
<p>{elapsed}s, double size {double}</p>
```

## Only synchronous reads are tracked

State read after an await or inside setTimeout within the effect is not a dependency. Read the values you depend on before any asynchronous step.

**Quiz:** Which is the best tool to compute fullName from firstName and lastName state?

- [ ] A setInterval that polls the values
- [ ] $effect that assigns to a $state variable
- [ ] $effect.pre
- [x] $derived

*Answer:* $derived. Derive state; reserve effects for side effects.
