Reputation: 383
So I have a function to run async, so put async inside useEffect, in below is my code
useEffect(() => {
const data = async () => {
const data = await getAllVertification();
if (!data.status) {
} else {
setAlldata(data.data);
setLoadingAction([]);
let tmp = [];
for (const element of data.data) {
tmp.push({ status: false });
}
setLoadingAction(tmp);
}
};
data();
}, [update]);
but got waning like this
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.
Can someone explain to me ?
Upvotes: 0
Views: 65
Reputation: 1597
Using a custom hook, we can do the following:
import { useAsyncEffect } from "use-async-effect2";
// ...
useAsyncEffect(function*(){
const data = yield getAllVertification();
if (data.status) {
setAlldata(data.data);
let tmp = [];
for (const element of data.data) {
tmp.push({ status: false }); // weird code
}
setLoadingAction(tmp);
}
};
}, [update]);
Upvotes: 0
Reputation: 819
You'll need to cancel the operations after await
resolves when the component is unmounted. Here's one of the ways to do this.
useEffect(() => {
let isSubscribed = true;
const data = async () => {
const data = await getAllVertification();
if(isSubscribed) {
if (!data.status) {
} else {
setAlldata(data.data);
setLoadingAction([]);
let tmp = [];
for (const element of data.data) {
tmp.push({ status: false });
}
setLoadingAction(tmp);
}
}
};
data();
return () => (isSubscribed = false);
}, [update]);
Upvotes: 1
Reputation: 774
rewriting you code to make it more clear:
useEffect(() => {
const getData = async () => {
const data = await getAllVertification();
if (!data.status) {
} else {
setAlldata(data.data);
setLoadingAction([]);
let tmp = [];
for (const element of data.data) {
tmp.push({ status: false });
}
setLoadingAction(tmp);
}
};
getData();
}, [update]);
Here getData
is an Async function which means that when you run it it returns a promise which will be executed at the end of the current event loop cycle.
You dont have to make getData
though.
Try this:
useEffect(() => {
getAllVertification().then(data => {
if (!data.status) {
} else {
setAlldata(data.data);
setLoadingAction([]);
let tmp = [];
for (const element of data.data) {
tmp.push({ status: false });
}
setLoadingAction(tmp);
}
}
}, [update]);
Upvotes: 0