Ref

ref lets you get access to DOM elements after they are mounted. In Kiru, the ref attribute accepts three forms:

  • a RefObject<Element | null> (created with ref())
  • a RefCallback<Element | null>
  • a Signal<Element | null>

Use ref() when you want an object with a stable .current property. This pattern is useful when you want to read the element during a lifecycle hook.

import { onMount, ref } from "kiru"

function App() {
  const buttonRefObject = ref<HTMLButtonElement>(null)

  onMount(() => {
    if (buttonRefObject.current) console.log("ref attached")
  })

  return () => <button ref={buttonRefObject}>Click Me</button>
}

Use a callback when you want direct control over how refs are handled.

function App() {
  const buttonRefCallback: Kiru.RefCallback<HTMLButtonElement | null> = (el) => {
    if (el) console.log("ref attached")
  }

  return () => <button ref={buttonRefCallback}>Click Me</button>
}

Passing a signal to ref works similarly to a ref object, but updates reactively. The signal receives null when detached and the element when attached.

import { signal } from "kiru"

function App() {
  const buttonSignal = signal<HTMLButtonElement | null>(null)

  buttonSignal.subscribe((elementOrNull) => {
    if (elementOrNull) console.log("ref attached")
  })

  return () => <button ref={buttonSignal}>Click Me</button>
}

Prefer a signal when you want reactive subscriptions to attachment/detachment, ref() when you want a simple .current object, and callbacks when you need custom imperative logic.

Related