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?
CodePudding user response:
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.
CodePudding user response:
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]);
CodePudding user response:
I have prevent mounting using this:
let storageRef = useRef(true);
useEffect(() => {
if (!storageRef.current) {
localStorage.setItem("cart", JSON.stringify(cart));
}
return () => { storageRef.current = false; }
}, [cart])
Is it a good idea?
