skip to Main Content

Why does assigning the setTimeSlotsList(fetchAPI(day)) create an infinite loop?

The code flow seems to be working when I just console.log(fetchAPI(day)) for testing.

const [timeSlotsList, setTimeSlotsList] = useState([])

function FormValues () {
  const { values } = useFormikContext();
  const day = new Date(values.date)

  useEffect(() => {
    setTimeSlotsList(fetchAPI(day))
  }, [values.date]);
}

const AvailableTimes = (props) => {
  const timeSlots = props.data.map(time =>
    <option value={time}>{time}</option>
  )
  return (
    <>{timeSlots}</>
  )
}

function updateTime (valueTime) {
  return (
    setTimeSlotsList(
      timeSlotsList.filter(a => a !== valueTime)
    )
  )
}

The fetchAPI function is shown below:

const seededRandom = function (seed) {
  var m = 2**35 - 31;
  var a = 185852;
  var s = seed % m;
  return function () {
    return (s = s * a % m) / m;
  };
}

const fetchAPI = function(date) {
  let result = [];
  let random = seededRandom(date.getDate());

  for (let i = 17; i <= 23; i++) {
    if (random() < 0.5) {
      result.push(i + ':00');
    }
    if (random() < 0.5) {
      result.push(i + ':30');
    }
  }
  return result;
};

2

Answers


  1. Chosen as BEST ANSWER

    I was able to resolve this by creating another useEffect call outside of the FormValues function which is causing the re-render that leads to infinite loop.

      useEffect(() => {
        const day = new Date(dateSelected)
            setTimeSlotsList(fetchAPI(day))
      }, [dateSelected]);
      
      const FormValues = () => {
        const { values } = useFormikContext();
    
          useEffect(() => {
            setDateSelected(values.date)
          }, [values.date]);
      }
    
    

    I am using Formik building this form which makes a bit complicated.


  2. The useEffect hook in React is designed to run its callback function whenever one of the dependencies in the dependency array changes.Here values.date is the dependency. So each time this changes useEffect runs. The effect runs when values.date changes, which triggers setTimeSlotsList(fetchAPI(day)).
    If fetchAPI(day) somehow triggers a change in values.date, a new render is triggered, and the useEffect runs again because values.date is a new object/reference. This creates a loop because values.date changes on every render.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search