I want to migrate my code from class to function in react
I was trying to understand the difference between these two react hooks
export const useEffectExceptOnMount = (effect: () => void, dependencies: Array<any>) => {
const mounted = useRef(false)
useEffect(() => {
if (mounted.current) {
effect()
return
} else {
mounted.current = true
}
}, dependencies)
// Reset on unmount for the next mount.
useEffect(() => {
return () => {
mounted.current = false
}
}, [])
}
And
export const useEffectExceptOnMount = (effect: () => void, dependencies: Array<any>) => {
const mounted = useRef(false)
useEffect(() => {
if (mounted.current) {
return () => {
effect()
}
} else {
mounted.current = true
}
}, dependencies)
// Reset on unmount for the next mount.
useEffect(() => {
return () => {
mounted.current = false
}
}, [])
}
(notice how effect()
is called) here..
When they are used like this in a component like this?
useEffectExceptOnMount(() => {
callUpdateApi()
}, [auth, person])
The difference is in the first version effect
is run every time the dependencies
are changed and consequently the useEffect
runs.
In the second one though the effect
is run during "effect clean up". Meaning it runs when new effect comes in and react cleans up previous effect. To see better use both at the same time:
import React, { useState, useEffect, useRef } from "react";
// custom hook to refer previous state
export const useEffectExceptOnMountA = (effect, dependencies) => {
const mounted = useRef(false);
useEffect(() => {
if (mounted.current) {
return () => {
effect();
};
} else {
mounted.current = true;
}
}, dependencies);
// Reset on unmount for the next mount.
useEffect(() => {
return () => {
mounted.current = false;
};
}, []);
};
export const useEffectExceptOnMountB = (effect, dependencies) => {
const mounted = useRef(false);
useEffect(() => {
if (mounted.current) {
effect();
return;
} else {
mounted.current = true;
}
}, dependencies);
// Reset on unmount for the next mount.
useEffect(() => {
return () => {
mounted.current = false;
};
}, []);
};
export default function Parent() {
let [s, set] = useState(0);
useEffectExceptOnMountA(() => {
console.log("A");
}, [s]);
useEffectExceptOnMountB(() => {
console.log("B");
}, [s]);
return (
<>
<button onClick={() => set((s) => s + 1)}>Go</button>
</>
);
}
Here once the Parent
is rendered if you click on Go
button, first time you see:
B
But if you click for the second time then the console looks like:
B <== from previous click
A
B
Here is the codesandbox and the documentationEffects with Cleanup
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.