0

Using Axios, I'm to render backend data from a utility file in my component.

In my useEffect hook, I have a conditional statement to check a selected date. If the date matches, I return a time slot that is available to book an appointment.

const [availableDates, setAvailableDates] = useState();
const [currentTimeSlot, setCurrentTimeSlot] = useState();
const [timeSlots, setTimeSlots] = useState();
  
useEffect(() => {
    async function getData(data) {
      let tempObjStoreData = service.getTempObjStoreData();
      let dates = await service.stepDate.getAvailableData();
      console.log('dates', dates);
      setAvailableDates(dates);
      setFlagRender(true);
      // this effect will run every time currentDate is changed
      if (availableDates) {
        console.log('show dates', dates);
        // get time slots of currentDate
        let slots;
        dates.forEach((d) => {
          debugger;
          if (isEqual(availableDates, new Date(d.date))) {
            slots = d.timeSlots;
          }
        });
        setTimeSlots(slots);
      }
    }
    return getData();
  }, [availableDates]);

When I test the component, I can select a date. However, the time slots are only briefly shown before disappearing. Looking at availableDates in my console log, I see that it is continuously being called.

Looking at other S/O questions like this one: React Hook useEffect : fetch data using axios with async await .api calling continuous the same api, the solution was empty brackets at the end of the useEffect hook:

example from solution

useEffect(() => {
    fetchData();
}, []); //This will run only once 

end of my useEffect hook

  }, [availableDates]);

However, if I remove this, I get the following error:

React Hook useEffect has a missing dependency: 'availableDates'.
Either include it or remove the dependency array.

How can I stop useEffect from constantly rendering this data?

4
  • just call getData() instead of return getData() inside the effect. Commented May 18, 2021 at 9:02
  • Move availableDates to ref (useRef) Commented May 18, 2021 at 9:02
  • 1
    When do you want to re-trigger a new fetch? you mentioned selected date but I don't see it in the code... Commented May 18, 2021 at 9:08
  • 1
    because your use effect working Re-cursively, you needed to change [availableDates] to [] and write another one [availableDates] only others action not use inside this setAvailableDates inside this useEffect Commented May 18, 2021 at 9:09

2 Answers 2

0

You don't need the availableDates as dependency because you only want to set it, not read from it. You probably want to add some selectedDate dependency as you would want to re-trigger a fetch when it changes.

I've also implemented a "dispose" function, because your async code might run after this component was removed from the DOM.

const [availableDates, setAvailableDates] = useState();
const [currentTimeSlot, setCurrentTimeSlot] = useState();
const [timeSlots, setTimeSlots] = useState();
  
useEffect(() => {
    let canceled = false;
    async function getData(data) {
      let tempObjStoreData = service.getTempObjStoreData();
      let dates = await service.stepDate.getAvailableData();
      if (canceled) {
         return; // ignore the result, as this `useEffect` was canceled
      }

      setAvailableDates(dates);
      setFlagRender(true);

      if (dates) {
        console.log('show dates', dates);
        // get time slots of currentDate
        let slots;
        dates.forEach((d) => {
          if (isEqual(dates, new Date(d.date))) {
            slots = d.timeSlots;
          }
        });
        setTimeSlots(slots);
      }
    }
    getData();

    return () => canceled = true;
    
  }, []);
Sign up to request clarification or add additional context in comments.

Comments

0

if I'm right, since availableDates is updated everytime useEffect runs, and also useEffect is triggered everytime availableDates is changed, so an infinite loop occurs. you can eliminate the use of availableDates in the useEffect dependencies by replacing it with the local variable dates

also, returning a function with useEffect means that it'll run before the component gets unmounted. so instead of returning, simply call the async function.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.