React Integration

Use Inval with React components, hooks, and the rendering lifecycle.

The Pattern

Inval is framework-agnostic. With React, you create Inval nodes outside components (or in refs) and subscribe to changes to trigger re-renders.

useInval.ts TYPESCRIPT
import { useRef, useEffect, useState } from 'react'
import { input, node, ComputedNode } from '@blu3ph4ntom/inval'

// Custom hook: creates an input node synced with React state
function useInvalInput<T>(initialValue: T) {
  const nodeRef = useRef<InputNode<T>>(input(initialValue))
  const [value, setValue] = useState(initialValue)

  useEffect(() => {
    nodeRef.current.set(value)
  }, [value])

  return [nodeRef.current, setValue] as const
}

// Custom hook: subscribes to a computed node
function useInvalNode<T>(computedNode: ComputedNode<T>) {
  const [value, setValue] = useState(() => computedNode.get())

  useEffect(() => {
    // Re-read when React re-renders (parent changed deps)
    setValue(computedNode.get())
  })

  return value
}

Example: Responsive Chart

Chart.tsx TYPESCRIPT
import { useRef, useEffect, useState } from 'react'
import { input, node } from '@blu3ph4ntom/inval'

// Create graph outside component
const containerWidth = input(800)
const chartWidth = node({
  dependsOn: { w: containerWidth },
  compute: ({ w }) => w * 0.8
})

function Chart() {
  const ref = useRef<HTMLDivElement>(null)
  const [width, setWidth] = useState(800)

  useEffect(() => {
    const el = ref.current
    if (!el) return

    const observer = new ResizeObserver(entries => {
      const w = entries[0].contentRect.width
      containerWidth.set(w)
      setWidth(w)
    })

    observer.observe(el)
    return () => observer.disconnect()
  }, [])

  const computedWidth = chartWidth.get()

  return (
    <div ref={ref}>
      <svg width={computedWidth} height={400}>
        {/* chart content */}
      </svg>
    </div>
  )
}

Warning

Don't create Inval nodes inside the component body — they'll be recreated on every render. Use useRef or module-level declarations.