My React app uses a slider component from Material UI. Its onChange event calls a function to update the state. I realized that my component rerenders for every slider step which is why I want to delay the updating of the state for like 300ms after the last time the slider was moved.
My approach is to start a timer with the state update via onChange. When the onChange is called again, the previous timer should be canceled though. This is the part I still struggle with.
The setSliderValue is a function which takes a number to update the state. How do I clear "timer" only when sliderChangeHandler is called again?
const [sliderValue, setSliderValue] = useState(20);
const sliderChangeHandler = (event, newValue) => {
const timer = setTimeout(setSliderValue, 300, newValue);
clearTimeout(timer);
};
You should set setTimeout
return value in your state:
const [sliderValue, setSliderValue] = useState(20);
const [timer, setTimer] = useState();
const sliderChangeHandler = (event, newValue) => {
clearTimeout(timer);
const newTimer = setTimeout(setSliderValue, 300, newValue);
setTimer(newTimer);
};
I would suggest to you to use this lib for debouncing any function: https://github.com/xnimorz/use-debounce
In your case it would be:
const [sliderValue, setSliderValue] = useState(20);
const debounced = useDebouncedCallback(
// function
setSliderValue,
// delay in ms
300,
);
// some part of the code
debounced.callback(30);
In this case every time you call debounced.callback
it will cancel previous call