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.

useSignal creates a piece of reactive state inside a component. It returns a getter and a setter: calling the getter reads the current value and registers a reactive dependency, while calling the setter writes a new value and notifies every effect or computed that depended on the previous read.

Signature

useSignal<T>(initialValue: T): [SignalGetter<T>, SignalSetter<T>]

Parameters

initialValue
T
required
The initial value of the signal. Inferred as the generic type T.

Return value

A two-element tuple [getter, setter]:
ElementTypeDescription
getterSignalGetter<T>() => TCall with no arguments to read the current value. Reading inside JSX props or useEffect / useComputed registers a reactive dependency.
setterSignalSetter<T>(value: T) => voidCall with a new value to update the signal and schedule any dependent effects or re-renders.

Example

A health bar that reactively adjusts its grayscale and brightness filters as health changes:
HealthBar.tsx
import { useSignal, useEffect } from 'tiny-engine/hooks'

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

  // Reactive props: () => health() is evaluated every time health changes
  const grayscale = () => (health() <= 0 ? 1 : 0)
  const brightness = () => health() / 100

  useEffect(() => {
    if (health() <= 0) {
      console.log('Player has died')
    }
  })

  return (
    <transform>
      <sprite
        textureId={HEALTH_BAR_TEXTURE}
        filters={{ grayscale, brightness }}
      />
      <clickable
        size={[64, 16]}
        onClick={() => setHealth(Math.max(0, health() - 10))}
      />
    </transform>
  )
}

Updating state based on the previous value

Because getter is a plain function, you can compose it directly:
counter.tsx
const [count, setCount] = useSignal(0)

const increment = () => setCount(count() + 1)
const reset = () => setCount(0)
Calling getter() (the first element of the tuple) inside a JSX prop expression — e.g. opacity={() => health() / 100} — creates a live reactive dependency. The prop will re-evaluate automatically whenever health is updated. If you pass a plain value like opacity={health() / 100} the expression is evaluated once at render time and will not update reactively.
Prefer small, focused signals over one large state object. Because each signal tracks its own subscribers, updating a single field won’t disturb components that only read other fields.

Build docs developers (and LLMs) love