Build a Reactivity Engine
Interactive lab

55 min

Effects and Cleanup

Support cleanup callbacks and disposeEffect to prevent leaks and duplicate listeners.

~/playground — 03-effects-and-cleanup · edit engine.js

Live
let activeEffect = null

export function createSignal(initial) {
  let value = initial
  const subscribers = new Set()
  return {
    get() {
      if (activeEffect) subscribers.add(activeEffect)
      return value
    },
    set(next) {
      value = next
      subscribers.forEach((fn) => fn())
    },
    subscribe(fn) {
      subscribers.add(fn)
      return () => subscribers.delete(fn)
    },
  }
}

export function createEffect(fn) {
  const effect = () => {
    activeEffect = effect
    fn()
    activeEffect = null
  }
  effect()
  return effect
}

Preview goal: This lab is test-driven — use Run tests to verify cleanup behavior.

Checkpoints

  • Cleanup runs before re-run and on dispose
  • All Sandpack tests pass