React Debounced Input Component
react-debounce-input is a React component that provides debounced `onChange` functionality for HTML input elements (like `<input>` or `<textarea>`) or any custom React component that follows the `value`/`onChange` prop pattern. It prevents excessive re-renders, state updates, or API calls during rapid user input by delaying the `onChange` callback until a specified `debounceTimeout` has elapsed since the last change. The current stable version is `3.3.0`, which added official React 18 support. The package maintains an active release cadence, addressing bug fixes, enhancing features (e.g., TypeScript support since v3.2.0, `inputRef` in v3.1.0), and keeping dependencies updated. Its primary differentiator is its straightforward, drop-in usability, enabling developers to easily integrate debouncing without writing custom logic, offering a simple alternative to more complex form libraries.
Common errors
-
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components)...
cause Attempting to use `DebounceInput` without a correct named import or via an incorrect default import.fixEnsure you are using `import { DebounceInput } from 'react-debounce-input';` to correctly import the named component. -
npm ERR! ERESOLVE unable to resolve dependency tree ... peer react@"^15.3.0 || 16 || 17 || 18" from react-debounce-input@3.3.0
cause Your project's `react` version does not satisfy the `react-debounce-input` peer dependency requirements.fixUpgrade your `react` and `react-dom` packages to a version compatible with `^15.3.0 || 16 || 17 || 18`. For example, `npm install react@18 react-dom@18`. -
TypeScript Error: Property 'value' does not exist on type 'EventTarget' or 'ChangeEvent<HTMLInputElement>'
cause Incorrectly typing the `event` parameter in the `onChange` handler, especially if the `element` prop is used with a custom component.fixEnsure the `event` parameter in your `onChange` handler is correctly typed, for example: `(event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => ...`.
Warnings
- breaking React versions older than 15.3.0 are no longer supported due to a major version update.
- gotcha Setting `debounceTimeout` to `-1` disables automatic debounced notifications completely. The `onChange` event will only be triggered when the `Enter` key is pressed.
- gotcha When the `minLength` prop is specified, if the input's value becomes shorter than this minimum (e.g., by deleting characters), an `onChange` event will be triggered with an empty string (`''`) as its value.
- gotcha The `forceNotifyByEnter` prop defaults to `true`. This can lead to unexpected behavior for `<textarea>` elements, where users might expect to insert new lines with `Enter` without triggering an immediate `onChange` notification.
- breaking Prior to version 3.0.1, using `onBlur` or `onKeyPress` props could cause issues where notifications were not correctly forced or handled transparently.
Install
-
npm install react-debounce-input -
yarn add react-debounce-input -
pnpm add react-debounce-input
Imports
- DebounceInput
import DebounceInput from 'react-debounce-input';
import { DebounceInput } from 'react-debounce-input'; - DebounceInputProps
import type { DebounceInputProps } from 'react-debounce-input'; - DebounceInput (CommonJS)
const { DebounceInput } = require('react-debounce-input');
Quickstart
import React, { useState } from 'react';
import ReactDOM from 'react-dom';
import { DebounceInput } from 'react-debounce-input';
interface AppState {
value: string;
}
const App: React.FC = () => {
const [value, setValue] = useState<string>('');
const handleChange = (event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
console.log('Debounced onChange triggered:', event.target.value);
setValue(event.target.value);
};
return (
<div style={{ fontFamily: 'sans-serif', padding: '20px' }}>
<h1>React Debounce Input Demo</h1>
<label htmlFor="debounced-input" style={{ display: 'block', marginBottom: '10px' }}>
Type here (min 2 chars, 300ms debounce):
</label>
<DebounceInput
id="debounced-input"
minLength={2}
debounceTimeout={300}
onChange={handleChange}
placeholder="Start typing..."
style={{ width: '300px', padding: '8px', fontSize: '16px', border: '1px solid #ccc', borderRadius: '4px' }}
/>
<p style={{ marginTop: '20px', fontSize: '1.1em' }}>
Current debounced value: <strong>{value}</strong>
</p>
<p style={{ color: '#666' }}>
This input will only update the displayed value after 300ms of no typing and when at least 2 characters have been entered.
Pressing Enter will also force a notification (by default).
</p>
</div>
);
};
const appRoot = document.getElementById('app-root') || document.createElement('div');
appRoot.id = 'app-root';
document.body.appendChild(appRoot);
ReactDOM.render(<App />, appRoot);