Debouncing

The debouncing pattern is crucial to UI development. Debouncing – and throttling – are used to moderate how much a function is called on a time basis.

When we debounce a function by 200ms, the function will be actually called only 200ms after the function has been called for the last time. If the function is called again before the timer ends, the timer is aborted, and another one is started; the function is not called.

There are many use cases for debouncing, mostly every time you want to perform time-consuming tasks. The one I genuinely love is search-as-you-type. There is a machine implementing it, so check it out!

Example

Try incrementing the counter by clicking the Increment button below. The counter will be incremented one second after you stop clicking the button.

The state machine is resilient to spamming. It controls how it should behave if the user abuses the button.

Count: 0

Debouncing

Code

View in GitHub
machine.ts
import { assign, setup } from "xstate";
export const debouncingMachine = setup({
types: {
events: {} as { type: "click" } | { type: "reset" },
context: {} as { counter: number },
},
actions: {
"Increment counter": assign({
counter: ({ context }) => context.counter + 1,
}),
"Reset counter": assign({
counter: 0,
}),
},
}).createMachine({
id: "Debouncing",
context: {
counter: 0,
},
initial: "Idle",
states: {
Idle: {
on: {
click: {
target: "Debouncing",
},
reset: {
actions: "Reset counter",
},
},
},
Debouncing: {
after: {
"1000": {
target: "Idle",
actions: "Increment counter",
},
},
on: {
click: {
target: "Debouncing",
description:
"Re-enter `Debouncing` state and reinitialize the delayed transition.",
reenter: true,
},
},
},
},
});

Get news from XState by Example

Sign up for the newsletter to be notified when more machines or an interactive tutorial are released. I respect your privacy and will only send emails once in a while.