Syntax
useEffect(() => {...}, [ dependencies ]);

Practical Example
Use cases of useEffect
With empty dependncy
useEffect(() => {
const storedUserData = localStorage.getItem("isLoggedIn");
if (storedUserData === "1") {
setIsLoggedIn(true);
}
}, []); //[] if this is empty then it run once page load then it wont triggered
With dependency
useEffect(() => {
const identifier = setTimeout(() => {
console.log("Checking form Validity");
setFormIsValid(
enteredEmail.includes("@") && enteredPassword.trim().length > 6
);
}, 500);
return () => {
console.log("CLEANUP");
clearTimeout(identifier); // clearing timeout
};
}, [enteredEmail, enteredPassword]);// Run every time enteredEmail and enteredPassword state changes
What to add & Not to add as Dependencies
In the previous lecture, we explored useEffect() dependencies.
You learned, that you should add “everything” you use in the effect function as a dependency – i.e. all state variables and functions you use in there.
That is correct, but there are a few exceptions you should be aware of:
- You DON’T need to add state updating functions (as we did in the last lecture with
setFormIsValid): React guarantees that those functions never change, hence you don’t need to add them as dependencies (you could though) - You also DON’T need to add “built-in” APIs or functions like
fetch(),localStorageetc (functions and features built-into the browser and hence available globally): These browser APIs / global functions are not related to the React component render cycle and they also never change - You also DON’T need to add variables or functions you might’ve defined OUTSIDE of your components (e.g. if you create a new helper function in a separate file): Such functions or variables also are not created inside of a component function and hence changing them won’t affect your components (components won’t be re-evaluated if such variables or functions change and vice-versa)
So long story short: You must add all “things” you use in your effect function if those “things” could change because your component (or some parent component) re-rendered. That’s why variables or state defined in component functions, props or functions defined in component functions have to be added as dependencies!
Here’s a made-up dummy example to further clarify the above-mentioned scenarios:
import { useEffect, useState } from 'react';
let myTimer;
const MyComponent = (props) => {
const [timerIsActive, setTimerIsActive] = useState(false);
const { timerDuration } = props; // using destructuring to pull out specific props values
useEffect(() => {
if (!timerIsActive) {
setTimerIsActive(true);
myTimer = setTimeout(() => {
setTimerIsActive(false);
}, timerDuration);
}
}, [timerIsActive, timerDuration]);
};
In this example:
timerIsActiveis added as a dependency because it’s component state that may change when the component changes (e.g. because the state was updated)timerDurationis added as a dependency because it’s a prop value of that component – so it may change if a parent component changes that value (causing this MyComponent component to re-render as well)setTimerIsActiveis NOT added as a dependency because it’s that exception: State updating functions could be added but don’t have to be added since React guarantees that the functions themselves never changemyTimeris NOT added as a dependency because it’s not a component-internal variable (i.e. not some state or a prop value) – it’s defined outside of the component and changing it (no matter where) wouldn’t cause the component to be re-evaluatedsetTimeoutis NOT added as a dependency because it’s a built-in API (built-into the browser) – it’s independent from React and your components, it doesn’t change
Credits: https://www.udemy.com/course/react-the-complete-guide-incl-redux/