Skip to content
Observe

useObserveThrottled

Runs a reactive effect throttled — fires at most once per ms milliseconds. Built on useObserveWithFilter. The selector always tracks dependencies; only the effect is throttled.

import {
import useObservable
useObservable
,
import useObserveThrottled
useObserveThrottled
} from "@usels/web";
function
function Component(): void
Component
() {
const
const position$: any
position$
=
import useObservable
useObservable
({
x: number
x
: 0,
y: number
y
: 0 });
// ✅ Effect fires at most once every 100ms
import useObserveThrottled
useObserveThrottled
(
() =>
const position$: any
position$
.
any
get
(),
(
value: any
value
) => {
any
console
.
any
log
("position:",
value: any
value
);
},
{
ms: number
ms
: 100 }
);
}

Control whether the effect fires at the leading edge (immediately on first change) or trailing edge (after the throttle window expires). By default, only the trailing edge fires.

import { useObservable, useObserveThrottled } from "@usels/web";
function Component() {
const mouseMove$ = useObservable({ x: 0, y: 0 });
// ✅ Fire immediately on first change (leading), then at the end of each throttle window (trailing)
useObserveThrottled(
() => mouseMove$.get(),
(value) => {
console.log("mouse moved:", value);
},
{ ms: 100, edges: ["leading", "trailing"] }
);
// ✅ Fire only on first change, skip throttled calls
useObserveThrottled(
() => mouseMove$.get(),
(value) => {
console.log("mouse started moving:", value);
},
{ ms: 100, edges: ["leading"] }
);
}

Pass immediate: true to execute the effect immediately on setup, in addition to triggering on source changes.

import { useObservable, useObserveThrottled } from "@usels/web";
function Component() {
const count$ = useObservable(0);
// ✅ Also executes the effect immediately with the initial value
useObserveThrottled(
() => count$.get(),
(value) => {
console.log("value:", value);
},
{ ms: 100, immediate: true }
);
}

The schedule option controls when the effect runs relative to Legend-State’s batch cycle.

  • schedule: 'sync' — runs synchronously inside the batch (equivalent to Legend-State immediate: true)
  • schedule: 'deferred' — runs after the batch ends (equivalent to Legend-State immediate: false)
  • omitted — uses Legend-State’s default batching
useObserveThrottled(count$, (v) => console.log(v), { ms: 100, schedule: "sync" });
export { observeThrottled, type ObserveThrottledOptions } from "./core";
export type UseObserveThrottled = typeof observeThrottled;
/**
* Runs a reactive effect throttled — fires at most once per `ms` milliseconds.
*
* Built on `watch` — lazy by default (`immediate: false`).
* The selector always tracks deps; only the effect is throttled.
*
* @param selector - Observable, array of Observables, or reactive read function.
* @param effect - Side-effect callback. Throttled. Always uses the latest closure.
* @param options - `ms` (default 200), `edges`, `immediate`, `schedule`.
*
* @example
* ```tsx twoslash
* // @noErrors
* import { useObserveThrottled } from "@usels/core";
* import { observable } from "@legendapp/state";
*
* const position$ = observable({ x: 0, y: 0 });
*
* useObserveThrottled(
* () => position$.get(),
* (value) => { console.log("position:", value); },
* { ms: 100 }
* );
* ```
*/
export declare const useObserveThrottled: UseObserveThrottled;

View on GitHub