Basically the title.
I can't wrap my head around it. What's the point of :
useEffect(() => {
//some code here
//couldn't this code be called outside of useEffect and only be ran once as well ?
}, []);
Bug: Clean up useEffect given [] empty dependency array causes a tedious linter error
New hook for useEffect and empty array
Bug: useEffect with no dependencies always fires a warning
reactjs - useEffect is now working when dependency is empty array - Stack Overflow
Videos
It's not quite the same.
Giving it an empty array acts like
componentDidMountas in, it only runs once.Giving it no second argument acts as both
componentDidMountandcomponentDidUpdate, as in it runs first on mount and then on every re-render.Giving it an array as second argument with any value inside, eg
, [variable1]will only execute the code inside youruseEffecthook ONCE on mount, as well as whenever that particular variable (variable1) changes.
You can read more about the second argument as well as more on how hooks actually work on the official docs at https://reactjs.org/docs/hooks-effect.html
Just an addition to @bamtheboozle's answer.
If you return a clean up function from your useEffect
useEffect(() => {
performSideEffect();
return cleanUpFunction;
}, []);
It will run before every useEffect code run, to clean up for the previous useEffect run. (Except the very first useEffect run)
I use useEffect all the time in my applications, but I've never understood the difference between having code inside a useEffect with no dependency array, and just running it in the component itself.
From the documentation. What is the difference between this
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
});
}and this?
function Example() {
const [count, setCount] = useState(0);
document.title = `You clicked ${count} times`;
}wont both run on every render?
Edit: thanks for all the helpful responses. It seems like my intuition was almost right. It does behave slightly differently, but almost never in a way you want. However it would be good for protecting DOM manipulating functions for SSR.
I'm guessing the only difference is that useEffect will guarantee that it will always run after the render, it also makes sure that every other component that needs to re-render will finish rendering before running the effect.
Though I can't really think of a good use case for this.
more or less the same, but you wouldn't do either of these things. you'd use the useEffect with a dependency array that has count.
otherwise you're doing unnecessary work. say this Example components' parent rerenders which causes Example to rerender, now we're changing the document title even though count never changed.
useEffect(() => {
(async() => {
// insert a row into database on server
})();
return () => {
console.log('unmounted');
(async() => {
// delete row in database on server
})();
}
});-
On initial mount of the component, the returned function will be called resulting on whatever I created on my server to be deleted
-
Anytime I update the state of the component, I get "unmounted" in console.log which means that updating states calls the returned function