Hooks

useDebouncedState

Reactive state with a debounced mirror. Write .current (e.g. bound to an input) and derive from .debounced - it settles delayms after the last write. Eliminates the common two-state + useDebounce wiring pattern. Built on useDebounce - the pending timer is cleared on teardown.

Basic search

Bind the input to .current and use .debounced to drive expensive operations - API calls, filtering, validation - that only need to run after typing pauses.

Immediate: (empty)

Debounced (300ms): (empty)

<script lang="ts">
  import { useDebouncedState } from 'sv5ui';

  const search = useDebouncedState('', 300);

  // search.current  - updates immediately on every keystroke
  // search.debounced - settles 300ms after the last keystroke
  const results = $derived(filterItems(search.debounced));
</script>

<input bind:value={search.current} placeholder="Search…" />
<p>Immediate: {search.current}</p>
<p>Debounced: {search.debounced}</p>

setImmediate for reset

Use setImmediate to flush both values synchronously without waiting for the debounce - ideal for clear/reset buttons.

Debounced: (empty)

<script lang="ts">
  import { useDebouncedState } from 'sv5ui';

  const query = useDebouncedState('', 400);

  function clear() {
    // setImmediate sets both current and debounced now,
    // cancelling any pending debounce
    query.setImmediate('');
  }
</script>

<input bind:value={query.current} placeholder="Search…" />
<button onclick={clear}>Clear</button>
<p>Debounced query: {query.debounced}</p>

Compared to useDebounce

useDebounce is a low-level scheduler - you call debounce.run(callback) imperatively. useDebouncedState is the ergonomic wrapper for the common pattern where you have an input and want to derive from its debounced value. If you need the extra control (flush, inline callback), use useDebounce directly.

Parameters

ParameterTypeDefault
initialT-
delaynumber300

Return

PropertyType-
currentT-
debouncedT (readonly)-
setImmediate(value: T) => void-