Skip to content

With Debounced State

The withDebouncedState hook creates a stateful store where updates are debounced — meaning only the latest value is applied after a defined delay.
This is ideal for user inputs, sliders, or any scenario where you don’t want to trigger reactions on every single change.


import { withDebouncedState } from 'phaser-hooks';
const search = withDebouncedState<string>(scene, 'search', '', 300);
// These rapid calls will be debounced
search.set('a');
search.set('ab');
search.set('abc'); // ✅ Only this final value is applied after 300ms
  • search.get() returns “abc”.
  • search.on('change') fires once with “abc”.

Here’s how you might use it for a search input or slider:

class SearchScene extends Phaser.Scene {
create() {
const search = withDebouncedState<string>(this, 'query', '', 300);
const input = this.add.dom(100, 100, 'input', { type: 'text' });
input.addEventListener('input', (e: any) => {
search.set(e.target.value);
});
// Only fires after user stops typing
search.on('change', (newQuery) => {
console.log('Searching for:', newQuery);
this.fetchResults(newQuery);
});
}
fetchResults(query: string) {
// Fetch or filter logic here...
}
}

Internally, this hook uses a regular withLocalState() and replaces only the set() method to debounce updates.

Use when:

  • You’re handling user input that fires too often (input, mousemove, sliders)
  • You need to reduce the frequency of network or logic updates
  • You want to throttle visual/UI updates for performance

🚫 Avoid when:

  • You need instant state updates (e.g. player position, physics)
  • You’re using it inside gameplay-critical loops

Create reusable debounced hooks:

hooks/withDebouncedScore.ts
import { withDebouncedState } from 'phaser-hooks';
export function withDebouncedScore(scene: Phaser.Scene) {
return withDebouncedState<number>(scene, 'score', 0, 200);
}