useInputGuards sits between a text input’s raw events and an expensive onCommit callback — a network request, store update, or analytics event you don’t want firing on every keystroke. The visible value stays fully responsive while the hook decides when a value is worth committing. The “guards” in the name are the protections it layers over that callback:
- Debounce — a burst of typing coalesces into a single commit with the final value.
- Commit guard — commits are rate-limited to at most one per
delayms, across every input method. - Held-key suppression — repeated
keydownfrom a held hotkey is dropped, so holding Enter or a paste shortcut doesn’t fire repeatedly. - Deduplication — the same value never commits twice in a row.
- External sync — when the
valueprop changes from outside, the input re-syncs and any stale in-flight commit is cancelled.
triggers option lets you opt out of any of them.
Installation
Usage
Call the hook with the controlledvalue, a delay, and your onCommit handler, then spread the returned inputProps onto the input. The hook owns the visible value and the commit timing; your component just reacts to commits.
inputProps carries value, onChange, onPaste, and onKeyDown. Spread all of them — the paste and keydown handlers are what make the guards work; dropping them falls back to plain debounced typing.
Configuration
| Prop | Type | Description |
|---|---|---|
value | string | The controlled value. Changing it from outside re-syncs the visible input and cancels stale commits. |
delay | number | Debounce and commit-guard window, in milliseconds. |
onCommit | (value: string) => void | Called with a value worth committing — debounced, rate-limited, and deduplicated. |
triggers | CommitTrigger[] | Which actions may commit. Omit (or pass empty) to enable all. |
Choosing which actions commit
Passtriggers to restrict which user actions fire a commit. When omitted, all are active.
Behavior reference
| Action / scenario | What happens |
|---|---|
| Typing | Visible value updates instantly; onCommit fires after delay ms of inactivity. |
| Paste | Inserted at the cursor (or over the selection); commits immediately through the guard. |
| Enter | Commits immediately if the guard is idle, otherwise defers until the guard window expires. |
| Clear to empty | onCommit('') fires immediately, bypassing the guard, and the guard is deactivated. |
| Rapid commits | First commits immediately; the next is deferred until delay ms have elapsed. |
| Held hotkeys | Repeated keydown is suppressed, so a held Enter or paste shortcut only fires once. |
| Held arrow keys | ArrowLeft / ArrowRight are exempt, so the cursor keeps moving as expected. |
| Repeat value | A value identical to the last committed one is never committed again. |
External value change | Visible value re-syncs, stale in-flight commits are cancelled, and the guard resets. |
| Unmount | All pending timers are cancelled; no trailing commit fires. |