34
loading...
This website collects cookies to deliver better user experience
useEffect(() => {
// actions performed when component mounts
return () => {
// actions to be performed when component unmounts
}
}, []);
useEffect
function is invoked depending on the second parameter of the useEffect
function.useEffect(() => {
if (loading) {
setUsername('Stranger');
}
}, [loading]);
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.
useEffect(() => {
setTimeout(() => {
setUsername('hello world');
}, 4000);
}, []);
useEffect(() => {
let mounted = true;
setTimeout(() => {
if (mounted) {
setUsername('hello world');
}
}, 4000);
}, []);
mounted
(you can call it subscribed or whatever) is true.mounted
variable will always be true, and thus doesn't prevent the warning or app leakage. So how and when do we make it false?useEffect(() => {
let mounted = true;
setTimeout(() => {
if (mounted) {
setUsername('hello world');
}
}, 4000);
return () => mounted = false;
}, []);
mounted
variable changes to false and thus the setUsername
function will not be updated when the component is unmounted.useEffect(() => {
// actions performed when component mounts
return () => {
// actions to be performed when component unmounts
}
}, []);
useEffect(() => {
let t = setTimeout(() => {
setUsername('hello world');
}, 4000);
return () => clearTimeout(t);
}, []);
fetch
API.useEffect(() => {
let mounted = true;
(async () => {
const res = await fetch('example.com');
if (mounted) {
// only try to update if we are subscribed (or mounted)
setUsername(res.username);
}
})();
return () => mounted = false; // cleanup function
}, []);
AbortController
interface for aborting the Fetch
requests rather than just preventing updates when unmounted.useEffect(() => {
const controller = new AbortController();
const signal = controller.signal;
(async () => {
const res = await fetch('example.com', {
signal,
});
setUsername(res.username));
})();
return () => controller.abort();
}, []);
setUsername
function because the request has been aborted. Just like the refactored setTimeout
example.