logo
Zess
Guide
API
Playground
English
简体中文
Guide
API
Playground
English
简体中文
logo
Zess

Getting Started

Introduction
Quick Start

Core

Basic Reactivity
Lifecycle
Components
Reactive Utilities
Store Utilities
Secondary Primitives
Rendering
JSX Attributes

Router

Components
Primitives
📝 Edit this page on GitHub
Previous pageComponents
Next pageStore Utilities

#Reactive Utilities

#untrack

Runs a function without tracking dependencies. This means that any signal accesses within the function won't create dependencies for the current tracking context.

Type:

untrack<T>(fn: Getter<T>): T

Parameters:

  • fn: The function to run without tracking

Returns: The return value of fn

Example:

const [count, setCount] = useSignal(0)

useEffect(() => {
  // This won't trigger a re-run when count changes
  const value = untrack(() => count())
  console.log('Count at effect start:', value)
})

#batch

Batches multiple state updates into a single re-render. This optimizes performance by ensuring that multiple changes to reactive values don't trigger multiple re-renders.

Type:

batch<T>(fn: Getter<T>): T

Parameters:

  • fn: A function containing multiple state updates

Returns: The return value of fn

Example:

const [count, setCount] = useSignal(0)
const [message, setMessage] = useSignal('')

function updateMultiple() {
  batch(() => {
    setCount(count() + 1)
    setMessage(`Count is now ${count() + 1}`)
    // Both updates are batched into a single re-render
  })
}

#on

Creates a function that runs when specified dependencies change. Similar to useEffect but returns a function that can be used in other contexts.

Type:

on<T extends Getter<any> | Getter<any>[], U>(deps: T, fn: OnEffectFunction<T, U>, defer?: boolean): Callback<U>

Parameters:

  • deps: A single getter or an array of getters that the effect depends on
  • fn: A function that runs when dependencies change. It receives the current values, previous values, and previous return value
  • defer: Optional flag to defer the first run until the next update cycle

Returns: A function that can be used as a callback in other effects or computations

Example:

const [count, setCount] = useSignal(0)
const [multiplier, setMultiplier] = useSignal(2)

const effectFn = on(
  [count, multiplier],
  ([currentCount, currentMultiplier]) => {
    console.log(`Result: ${currentCount * currentMultiplier}`)
  },
)

// Use the effect function in another effect
useEffect(effectFn)

#createRoot

Creates a new untracked owner scope that doesn't automatically dispose. Useful for nested reactive scopes that shouldn't be disposed when their parent recomputes. Ensures all memory and computations are properly managed.

Type:

createRoot<T>(fn: (dispose: () => void) => T, detachedOwner?: Owner): T

Parameters:

  • fn: The function to execute within the root context. It receives a dispose function as an argument
  • detachedOwner: Optional owner context to attach to

Returns: The return value of fn

Example:

const root = createRoot((dispose) => {
  const [count, setCount] = useSignal(0)

  // Do something with the signal
  setCount(10)
  console.log(count()) // 10

  // Return any values you want to access outside the root
  return { count, setCount, dispose }
})

// Later, when you want to clean up the root
root.dispose() // Cleans up the root and all its dependencies

#getOwner

Gets the current owner context. The owner context is responsible for managing the lifecycle of computations and effects.

Type:

getOwner(): Owner | undefined

Returns: The current owner or undefined if none

Example:

const owner = getOwner()
if (owner) {
  // Do something with the owner, like attaching effects or computations
}

#runWithOwner

Runs a function within a specific owner context. This allows you to create computations or effects that are managed by a specific owner.

Type:

runWithOwner<T>(owner: Owner, fn: Getter<T>): T

Parameters:

  • owner: The owner context to use
  • fn: The function to run

Returns: The return value of fn

Example:

const owner = getOwner()
if (owner) {
  runWithOwner(owner, () => {
    // Code executed within the owner context
    const [count] = useSignal(0)
    // This signal will be managed by the specified owner
  })
}

#mapArray

Maps an array to a new array with efficient updates by tracking each value's identity. This is the underlying function for the <For> component.

Type:

mapArray<T, U>(list: Getter<readonly T[] | false | null | undefined>, mapFn: (v: T, i: Getter<number>) => U, fallback?: Getter<any>): Getter<U[]>

Parameters:

  • list: A getter function that returns the array to map or a falsy value
  • mapFn: A function that maps each item to a new value, receiving the item and a reactive index
  • fallback: Optional function that returns fallback content when the array is empty

Returns: A getter function that returns the mapped array

Example:

const [numbers, setNumbers] = useSignal([1, 2, 3])
const doubledNumbers = mapArray(
  () => numbers(),
  (num) => num * 2,
  () => [0], // Fallback when array is empty
)
console.log(doubledNumbers()) // [2, 4, 6]

#indexArray

Maps an array to a new array with efficient updates by tracking changes to array indices. This is the underlying function for the <Index> component.

Type:

indexArray<T, U>(list: Getter<readonly T[] | false | null | undefined>, mapFn: (v: Getter<T>, i: number) => U, fallback?: Getter<any>): Getter<U[]>

Parameters:

  • list: A getter function that returns the array to map or a falsy value
  • mapFn: A function that maps each item to a new value, receiving a reactive getter for the item and the static index
  • fallback: Optional function that returns fallback content when the array is empty

Returns: A getter function that returns the mapped array

Example:

const [items, setItems] = useSignal(['a', 'b', 'c'])
const indexedItems = indexArray(
  () => items(),
  (item, index) => ({ value: item(), position: index }),
)
console.log(indexedItems()) // [{ value: 'a', position: 0 }, ...]

#mergeProps

Merges multiple props objects into a single reactive object. Properties from later sources override earlier ones. Useful for setting default properties for components when callers don't provide them.

Type:

mergeProps<T extends any[]>(...sources: T): MergeResult<T>

Parameters:

  • sources: Multiple props objects or functions that return props objects

Returns: A merged object with reactive properties

Example:

const defaults = { color: 'blue', size: 'medium' }
const userProps = { color: 'red', fontWeight: 'bold' }
const merged = mergeProps(defaults, userProps)

console.log(merged.color) // 'red'
console.log(merged.size) // 'medium'
console.log(merged.fontWeight) // 'bold'

// Sources can also be functions
const dynamicProps = mergeProps(defaults, () => ({
  color: isDarkMode() ? 'white' : 'black',
}))

#splitProps

Splits a props object into multiple objects based on specified keys. Useful for separating props for different components or hooks.

Type:

splitProps<T extends object, const U extends (keyof any)[][]>(props: T, ...keys: U): SplitResult<T, U>

Parameters:

  • props: The props object to split
  • keys: Arrays of keys to extract into separate objects

Returns: An array of objects with the extracted props and remaining props

Example:

const props = { id: 1, name: 'John', age: 30, city: 'New York' }
const [userInfo, location, rest] = splitProps(props, ['id', 'name'], ['city'])

console.log(userInfo) // { id: 1, name: 'John' }
console.log(location) // { city: 'New York' }
console.log(rest) // { age: 30 }

#catchError

Executes a function and catches any errors that occur, passing them to an error handler. Useful for isolating error handling within specific parts of your application.

Type:

catchError<T>(fn: Getter<T>, handler: (error: unknown) => void): T

Parameters:

  • fn: The function to execute
  • handler: A function to handle any errors

Returns: The return value of fn if no error occurs

Example:

const result = catchError(
  () => {
    if (Math.random() > 0.5) throw new Error('Random error')
    return 'Success'
  },
  (error) => {
    console.log('Caught error:', error.message)
  },
)