Reputation: 3954
I have a datepicker component I'm making. There are three 'dials', for days, months and years, which are moved by dragging the mouse within column divs. It works great, except it updates really fast and the whole thing moves too quickly. How do I make sure it updates only at set intervals?
My useEffect code is:
useEffect(() => {
if (mouseState.mouseIsDown && mouseState.dateField === 'year') {
getYear();
} else if (date) {
setNewStartDate();
}
if (mouseState.mouseIsDown && mouseState.dateField === 'month') {
getMonth();
} else if (date) {
setNewStartDate();
}
if (mouseState.mouseIsDown && mouseState.dateField === 'day') {
getDay();
} else if (date) {
setNewStartDate();
}
},
[ mouseState.mouseIsDown, mouseState.dateField, endPositionYYear, endPositionYMonth, endPositionYDay ]
);
My getYear function is like so:
const getYear = () => {
getPositions('year');
if (startDate.getFullYear() >= 1911 || (endPositionYYear < 0 && startDate.getFullYear() === 1911)) {
if (endPositionYYear > prevEndPositionYYear) {
setMyDate(new Date(year - 1, month, day));
} else {
setMyDate(new Date(year + 1, month, day));
}
} else if (startDate.getFullYear() < 1911 && endPositionYYear > 0) {
setMyDate(new Date(year + Math.round(endPositionYYear / 10), month, day));
}
};
If I set Timeouts during the getYear function, the useEffect hook with receive new Y position coordinates from mouseState.mouseIsDown, which stores the Y coordinates of the mouse while the left mouse button is down, before the timeout has elapsed, and the function call will be overridden by the latest call to getYear? I think?
Is there any way of making sure getYear only gets called every 500ms say?
Upvotes: 0
Views: 975
Reputation: 139
You can improve by your needs.
// 0 is no limit
function useDebounce(callFn, callCount = 0 , time = 1000){
const timeout = useRef(); // to clear interval in anywhere
const counter = useRef(0);
function clear(){
timeout.current && clearInterval(timeout.current);
counter.current = 0;
}
useEffect(() => {
timeout.current = setInterval(() => {
callFn(counter.current++); // pass call-count, it may be useful
if(callCount > 0 && counter.current == callCount){
timeout.current && clearInterval(timeout.current);
}
}, time);
return clear
}, []);
return useCallback(() => clear(), []);
}
Upvotes: 1