I want to debounce the value coming from <SomeComp onChange. The onChange callback is defined as (value: string) => void
So I did this:
function MyComponent(onDebounceChange) {
const [value, setValue] = useState('');
const debouncedValue = useDebounce(value, 500);
useEffect(() => {
onDebounceChange?.(debouncedValue);
}, [debouncedValue]);
return <SomeComp onChange={setValue} />
}
function useDebounce<T>(value: T, delay: number = 500): T {
const [debouncedValue, setDebouncedValue] = useState<T>(value);
useEffect(() => {
const timeoutId = setTimeout(() => setDebouncedValue(value), delay);
return () => {
clearTimeout(timeoutId);
};
}, [value, delay]);
return debouncedValue;
}
However the onDebounceChange callback is called on render and HMR. Vite is doing the HMR.
I can fix the render callback by using an initial state.
const [initial, setInitial] = useState(true);
useEffect(() => {
setInitial(false);
}, []);
useEffect(() => {
if (initial) return;
onDebounceChange?.(debouncedValue);
}, [debouncedValue]);
But that doesn't fix callbacks triggered by HMR.
How do I prevent these programmatical callbacks. I only ever want these callbacks when a user interacted with the UI.
I do not have access to the "raw" <input onChange>. All I have is <SomeComp onChange={} />