onMount & onCleanup: Owner Scope Root Disposers & Teardowns
- Last updated
- Prerequisites:
- SolidJS Components Run Once
- createEffect lifecycle
- solidjs
- lifecycle
- onMount
- onCleanup
- owner
- disposer
- memory
Read at your depth
The practical view
SolidJS has only two primary lifecycle methods: `onMount` and `onCleanup`. `onMount(fn)` runs once after the component's initial DOM nodes have been created and mounted into the document (ideal for DOM measurements or external library initialization). `onCleanup(fn)` registers a teardown function that runs when the current reactive scope (component, effect, or memo) is destroyed or re-evaluated.
The same idea in other frameworks
`useEffect(() => { init(); return () => cleanup(); }, [])`.`ngOnInit` / `afterNextRender` paired with `ngOnDestroy` / `DestroyRef`.`onMounted(() => ...)` and `onUnmounted(() => ...)`.`$effect(() => { init(); return () => cleanup(); })`.Legacy vs modern
React useEffect Multi-Phase Lifecycle vs Solid onMount / onCleanup
React's `useEffect` combines mount, update, and teardown into one hook; Solid separates initial DOM mount from granular disposal scopes.
useEffect(() => { const timer = setInterval(...); return () => clearInterval(timer); }, []); // ❌ Re-runs in StrictModeonMount(() => { ... }); onCleanup(() => clearInterval(id)); // ✅ NEW: Clear, deterministic lifecycleInterview gotchas
Context
Tests deep understanding of Solid's reactive scope tree.
The mechanical answer
`onCleanup` **can be called inside any reactive scope**, including inside a `createEffect`, `createMemo`, custom directive, or `<For>` row. When called inside a `createEffect`, the cleanup function executes **every time the effect is about to re-run** (before new execution) as well as when the parent component unmounts.
Trap
Do not assume `onCleanup` only runs on component unmount; when nested inside an effect, it runs on every reactive dependency change before the next run.
Context
Checks knowledge of isomorphic SSR execution boundaries.
The mechanical answer
No. `onMount` **never runs on the server during SSR**. It is strictly a client-side lifecycle hook that executes after the real browser DOM nodes have been created and inserted into the document. Server-side code executes only the synchronous component setup pass.
Trap
Placing browser-only code (like `window.localStorage` or `document.querySelector`) outside of `onMount` in the root component body will crash during SSR.