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
| Parameter | Type | Default |
|---|---|---|
initial | T | - |
delay | number | 300 |
Return
| Property | Type | - |
|---|---|---|
current | T | - |
debounced | T (readonly) | - |
setImmediate | (value: T) => void | - |