Been using react material UI and want to use TextField that is both debounced (or throttled) and controlled.
controlled - the persistence value is held somewhere else and the component accepts the value and a onChange function as props.
debounced - the onChange function is called only when the user stops typing for a given amount of milliseconds. Of course for coherent display the component might hold an innerValue state.
I want the usage to be like this, with other props of TextField also relayed to the internal implementation
<TextFieldDebounced value={value} onChange={v => setValue(v)} debounceMs={500} />
Been looking for this for some time now and there are few webpages about the subject but couldn't create such a component.
Many thanks for all who answers.
Try this solution.
import TextField, { TextFieldProps } from "@mui/material/TextField";
type DebouncedTextFieldProps = {
value: string;
onChange: (value: string) => void;
delay?: number;
icon?: ReactNode;
} & Omit<TextFieldProps, "value" | "onChange">; //combination of custom props & TextFieldProps
const DebouncedInput: React.FC<DebouncedTextFieldProps> = ({
value,
onChange,
delay = 500,
placeholder = "Type here...",
...rest
}) => {
const [inputValue, setInputValue] = useState(value);
useEffect(() => {
setInputValue(value);
}, [value]);
useEffect(() => {
const handler = setTimeout(() => {
if (inputValue !== value) {
onChange(inputValue);
}
}, delay);
return () => {
clearTimeout(handler);
};
}, [inputValue, delay, value, onChange]);
return (
<TextField
{...rest} //rest of the TextField props
value={inputValue}
placeholder={placeholder}
onChange={(e) => setInputValue(e.target.value)}
/>
);
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With