Overview
A Mates component is a function that returns a function. The outer function is the setup phase: it runs exactly once when the component mounts. Create atoms, define event handlers, register onMount / onCleanup, and kick off one-time work there.
The inner function is the render phase: it re-runs every time a reactive dependency changes. Reading an atom with count() or calling propsFn() inside it registers that dependency — no dependency arrays, no manual wiring. Its only job is to return an html template; keep it free of side effects.
This split is why Mates is fast: the setup never re-runs, and only the components whose atoms actually changed re-render their inner functions. There is no virtual DOM diffing — the reactive graph drives targeted DOM patches directly.
What goes where — a placement guide
|
Code
|
Layer
|
Why
|
|---|---|---|
const count = atom(0)
| Setup | Created once. Every render reads the same atom. |
onMount(() => { … })
| Setup | Lifecycle hooks run once per mount. Return a cleanup function to tear down. |
const increment = () => …
| Setup | Handlers are created once and close over atoms — no stale closures. |
loadData() / fetch
| Setup |
One-time work. Better: an asyncAction for loading/error state.
|
propsFn()
| Render | Returns the latest props on every render. |
count() inside html
| Render | Reading an atom is what registers the dependency that drives re-renders. |
x(Child, props)
| Render | Embedding children is render work. |
setInterval(…)
| Render |
A new interval on every update. Use onInterval in setup.
|
count.set(…)
| Render | Writing during render re-triggers the render — infinite loop. |
const { name } = propsFn()
| Setup | Destructured once = frozen forever. Destructure inside the render. |
Watch the two layers run
Press Trigger update: the render counter
climbs while setup stays at 1×. The outer function ran
exactly once; every click re-runs only the inner function.
A complete component
The same model in a realistic shape: state and handlers in setup, a template that reads atoms in render.
Component with props
Props arrive as the first argument —
propsFn — a function you call inside the render to get
the latest values. Each time the parent re-renders,
propsFn() returns the updated props.