I have configured the useEffect to run only when its dependencies changes:
useEffect(() => { localStorage.setItem("cart", JSON.stringify(cart)); }, [cart]) But when the component renders for the first time. useEffect hook will call Why?
That's just how useEffect works. All callbacks will run when the component mounts no matter the dependency array - no matter what values are in it, no matter whether it's empty, no matter whether it's even present at all.
If you want to avoid this, you can check if the cart is equal (===) to the cart's initial value.
const [cart, setCart] = useState(initialCart); useEffect(() => { if (cart !== initialCart) { localStorage.setItem("cart", JSON.stringify(cart)); } }, [cart]); In the case where comparing directly could produce false positives - like if the state was a primitive rather than an array, and so could be === to the initial value despite not being in the initial render - you'll need another way to check whether the component's mounted or not, such as by having an isMounted state or ref.
useEffect run at least one time to prevent that you should use a state to detect the first render in your component.
const [cart, setCart]=useState(initialCart); const [didRender, setDidRender]=useState(false); useEffect(()=>{ setDidRender(true); },[]); useEffect(()=>{ if(didRender){ //Your code } },[cart]); You can use custom hook to run use effect after mount.
const useEffectAfterMount = (cb, dependencies) => { const mounted = useRef(true); useEffect(() => { if (!mounted.current) { return cb(); } mounted.current = false; }, dependencies); // eslint-disable-line react-hooks/exhaustive-deps }; Here is the typescript version:
const useEffectAfterMount = (cb: EffectCallback, dependencies: DependencyList | undefined) => { const mounted = useRef(true); useEffect(() => { if (!mounted.current) { return cb(); } mounted.current = false; }, dependencies); // eslint-disable-line react-hooks/exhaustive-deps }; Example:
useEffectAfterMount(() => { localStorage.setItem("cart", JSON.stringify(cart)); }, [cart])