I am currently using firestore but I am currently getting problems with memory leakage as I delete transactionally delete my component just before I leave the screen what is the best way I to avoid this leakage When I click on the link component I want to remove the notification from the database it seems to work and take me to the new page the only problem is that I get a memory leak how should I avoid this.
const loadAlerts = useCallback(() => {
const alertNotifcationsObserver = onSnapshot(notifications, (querySnapshot) => {
const alertData: any[] = []
querySnapshot.forEach((doc) => {
console.log(doc.data())
alertData.push({
...doc.data(),
doc
})
});
setAlertNotifcations(alertData)
});
return alertNotifcationsObserver
}, [notifications])
useEffect(() => {
loadAlerts();
console.log(alertNotifications)
}, []);
<IonItem onClick={async (e) => {
console.log(i.Reference)
await notificationsController(i.Reference)
}} key={i.Reference} lines='full'>
<Link
to={{
pathname: i.Link,
state: { documentReferencePath: i.Reference }
}}
>
{i.Type}
</Link>
</IonItem>
const notificationsController = async(documentReferencePath:string)=>{
try {
await runTransaction(db, async (transaction) => {
const documentReference = doc(db,documentReferencePath)
const notificationDoc = await transaction.get(documentReference);
if (!notificationDoc.exists()) {
throw "Document does not exist!";
}
transaction.delete(documentReference)
});
console.log("Notification removed successfully committed!");
} catch (e) {
console.log("Transaction failed: ", e);
}
index.js:1 Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
How do I get rid of this error also I tried to add unsubscribe for loadAlerts but type script gives me a error too.
Argument of type '() => () => Unsubscribe' is not assignable to parameter of type 'EffectCallback'.
CodePudding user response:
It seems unlikely you'll call the loadAlerts
function outside the useEffect
hook or in any other callback, move it into the useEffect
hook to remove it as a dependency, and return a cleanup function from the useEffect
to unsubscribe.
useEffect(() => {
const unsubscribe = onSnapshot(
notifications,
(querySnapshot) => {
const alertData: any[] = querySnapshot.map((doc) => ({
...doc.data(),
doc,
}));
setAlertNotifcations(alertData)
});
return unsubscribe;
}, []);