Skip to content

Instantly share code, notes, and snippets.

@MarekZeman91
Created May 12, 2025 12:56
Show Gist options
  • Save MarekZeman91/9f9b718980167a0e95897696b6e1e42a to your computer and use it in GitHub Desktop.
Save MarekZeman91/9f9b718980167a0e95897696b6e1e42a to your computer and use it in GitHub Desktop.
Create an input field that will avoid React "onChange" and has debounce functionality.
import { type FC, useEffect, useRef, type InputHTMLAttributes, type ChangeEvent } from 'react';
export interface InputField extends InputHTMLAttributes<HTMLInputElement> {
debounceTimeout: number;
}
export const InputField: FC<InputField> = ({ value: defaultValue, onChange, debounceTimeout = 1, ...props }) => {
const timeoutInfo = useRef({ onChange, timeout: 0 });
Object.assign(timeoutInfo.current, { onChange });
const setDebouncedValue = (e: ChangeEvent<HTMLInputElement>) => {
const scope = timeoutInfo.current;
if (debounceTimeout === 0) {
return scope.onChange?.(e);
}
window.clearTimeout(scope.timeout);
scope.timeout = window.setTimeout(() => {
scope.onChange?.(e);
}, debounceTimeout);
};
useEffect(() => () => window.clearTimeout(timeoutInfo.current.timeout), []);
return <input {...props} defaultValue={defaultValue} onChange={setDebouncedValue} />;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment