Reputation: 17
I'm developing an autosave component in React.
My logic is whenever the "bestOf" changes, I check with an async fetch function if the data is equal to the data that is stored in my database.
handleSave
functionI am now trying to cleanup this timeout in order to not call this function multiple times if multiple modifications to the bestOf occurs but the useEffect cleanup function doesn't work in my case.
Here is my try with clearTimeout
useEffect(() => {
let timeout;
const compareSave = async () => {
await fetch(`/api/bestof/get?bestof_id=${bestOf.id}`)
.then((res) => res.json())
.then((data) => {
if (JSON.stringify(data) === JSON.stringify(bestOf)) {
return setSave("saved");
} else {
setSave("unsaved");
timeout = setTimeout(() => {
handleSave();
}, 5000);
}
})
.catch((err) => console.log(err));
};
compareSave();
return () => {
clearTimeout(timeout);
};
}, [bestOf]);
And here is another try with AbortController
useEffect(() => {
const controller = new AbortController();
const compareSave = async () => {
await fetch(`/api/bestof/get?bestof_id=${bestOf.id}`, {
signal: controller.signal,
})
.then((res) => res.json())
.then((data) => {
if (JSON.stringify(data) === JSON.stringify(bestOf)) {
return setSave("saved");
} else {
setSave("unsaved");
setTimeout(() => {
handleSave();
}, 5000);
}
})
.catch((err) => console.log(err));
};
compareSave();
return () => {
controller.abort()
};
}, [bestOf]);
Both solutions doesn't work and the timeout function is executed multiple time for each modification. Any suggestions ?
Upvotes: 1
Views: 482
Reputation: 17
After a lot of tries i finally found that I need to add a flag to ignore the stuff after fetch in the timeout for if bestOf changes.
Otherwise because it is async, the timeout would be set after I have cleared it.
useEffect(() => {
let shouldIgnore = false;
let timeout;
const compareSave = async () => {
await fetch(`/api/bestof/get?bestof_id=${bestOf.id}`)
.then((res) => res.json())
.then((data) => {
if (shouldIgnore) {
return;
}
if (JSON.stringify(data) === JSON.stringify(bestOf)) {
return setSave('saved');
} else {
setSave('unsaved');
timeout = setTimeout(() => {
handleSave();
}, 5000);
}
})
.catch((err) => console.log(err));
};
compareSave();
return () => {
shouldIgnore = true;
clearTimeout(timeout);
};
}, [bestOf]);
Upvotes: 1