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
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.
I am using Formik building this form which makes a bit complicated.
The
useEffect
hook in React is designed to run its callback function whenever one of the dependencies in the dependency array changes.Herevalues.date
is the dependency. So each time this changes useEffect runs. The effect runs when values.date changes, which triggerssetTimeSlotsList(fetchAPI(day))
.If
fetchAPI(day)
somehow triggers a change in values.date, a new render is triggered, and theuseEffect
runs again because values.date is a new object/reference. This creates a loop because values.date changes on every render.