React MUI TextField with Debounce

120 Views Asked by At

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.

1

There are 1 best solutions below

0
remedy_man On

You can achieve this by attaching a debounce function to a useCallback hook to prevent react from changing the debounced function's reference in subsequent re-renders.

type Props = {
  debounceMs?: number;
  onChange: (p: string) => void;
  value: string;
};

const TextFieldDebounced: React.FC<Props> = ({
  debounceMs = 300,
  onChange,
  value = '',
}) => {
  const debouncedChangeHandler = React.useCallback(
    debounce(onChange, debounceMs),
    []
  );

  const handleChange = ({ target }: React.ChangeEvent<HTMLInputElement>) => {
    debouncedChangeHandler(target.value);
  };

  return <TextField value={value} onChange={handleChange} />;
};

This is the debounce function I use in multiple codebases

function debounce<T>(func: (...param: T[]) => void, timeout = 3000) {
  let timer: number;

  return (...args: T[]) => {
    window.clearTimeout(timer);
    timer = window.setTimeout(func, timeout, ...args);
  };
}

Here is a complete working sample on stackblitz