Search code examples
reactjsreact-hookscallbackuse-effect

React cancel callback when calling it multiple times


Im trying to update some code. You can change dates and when you change a day the useEffect() is called. The problem is that you can click on a new date whenever the first promise is still loading. I want to cancel the promise that is made first and only accept the last one clicked. E.g startDate = 01-04-2022 and then select 02-04-2022, 03-04-2022 etc.

const getData = useCallback((): void => {
    const selectedDate = dateParam ? new Date(dateParam) : new Date();

    myApiCall(selectedDate)
        .then((result: //variable here) => {
            //do stuff with result and set data
            setData(result);
        })
        .catch((err) => {
           //if error occurs
            console.log('Error: ', err);
        })
        .finally(() => {
            //set loading to false so no memory leak can occur
            setLoading(false);
        });
}, []);

useEffect(() => {
    setLoading(true);
    getData();

    const interval = setInterval(() => {
        getData();
    }, 30000);

    return () => clearInterval(interval);
}, [getData]);

I'm stuck on the code but I was hoping someone could help out. Thanks in advance for feedback and such.


Solution

  • debounce from loadash should probably help you with this.

    import debounce from 'lodash.debounce';
    
    const yourFunction = () => {
        const selectedDate = dateParam ? new Date(dateParam) : new Date();
    
        myApiCall(selectedDate)
            .then((result: //variable here) => {
                //do stuff with result and set data
                setData(result);
            })
            .catch((err) => {
               //if error occurs
                console.log('Error: ', err);
            })
            .finally(() => {
                //set loading to false so no memory leak can occur
                setLoading(false);
            });
    }
    
    const getData = useCallback((): void => {
       debounce(yourFunction, 300) // value 300 is in ms - its just treshold you can change it to any value you want
    }, []);
    

    Now when user click on change date multiple times and then he stop for 3 seconds (300ms) only latest click will be trigerred