Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/sanchedev/tiny-engine/llms.txt

Use this file to discover all available pages before exploring further.

useEffect registers a side-effect function that is re-run whenever any signal read inside the function changes. The effect does not run immediately at component setup time; it runs for the first time when the component’s root node starts, and re-runs on every subsequent change to a tracked signal. An optional cleanup function returned from fn is called before the next run and when the node is destroyed.

Signature

useEffect(fn: () => void | (() => void)): void

Parameters

fn
() => void | (() => void)
required
The effect function. Any SignalGetter called inside it becomes a tracked dependency. The function can optionally return a cleanup callback that is invoked before the effect re-runs or when the node is destroyed.

Return value

voiduseEffect does not return a value.

Examples

Logging health changes

Player.tsx
import { useSignal, useEffect } from 'tiny-engine/hooks'

function Player() {
  const [health, setHealth] = useSignal(100)

  useEffect(() => {
    console.log('Health changed:', health())

    // Cleanup runs before the next effect execution
    return () => {
      console.log('Cleaning up previous health log')
    }
  })

  return (
    <transform>
      <clickable
        size={[32, 32]}
        onClick={() => setHealth(health() - 10)}
      />
    </transform>
  )
}

Syncing external state

ScoreDisplay.tsx
import { useSignal, useEffect } from 'tiny-engine/hooks'

function ScoreDisplay() {
  const [score, setScore] = useSignal(0)

  useEffect(() => {
    // Keep the DOM in sync whenever score changes
    const el = document.getElementById('score-display')
    if (el) el.textContent = `Score: ${score()}`

    return () => {
      // Cleanup: clear the display when this node is destroyed
      const el = document.getElementById('score-display')
      if (el) el.textContent = ''
    }
  })

  return <transform />
}

Multiple tracked signals

StatusHUD.tsx
import { useSignal, useEffect } from 'tiny-engine/hooks'

function StatusHUD() {
  const [health, setHealth] = useSignal(100)
  const [mana, setMana] = useSignal(50)

  // Runs whenever *either* health or mana changes
  useEffect(() => {
    console.log(`HP: ${health()}  MP: ${mana()}`)
  })

  return <transform />
}
Unlike React’s useEffect, tiny-engine’s useEffect does not run on initial mount. It runs reactively: the first execution happens when the node’s started event fires (not when the component function is called), and subsequent executions happen only when a tracked signal changes. There is no dependency array — tracking is automatic and dynamic.
If you only need to run code once on mount without signal tracking, use useMount instead. useMount runs once when the node starts and once more (for cleanup) when it is destroyed.

Build docs developers (and LLMs) love