0

I'm developing a cart system and the problem is that, when I add a product to the cart, it works in context and localStorage; but, when I refresh, the data is gone.

const dispatch = useDispatch();
const {
  cartItems
} = useSelector((state) => state.cart)
const [cartState, setCartState] = useState({
  cartItems: [],
})
const initialRender = useRef(true);
useEffect(() => {
  if (JSON.parse(localStorage.getItem("cartState"))) {
    const storedCartItems = JSON.parse(localStorage.getItem("cartState"));
    setCartState([...cartItems, ...storedCartItems]);
  }
}, []);
useEffect(() => {
  if (initialRender.current) {
    initialRender.current = false;
    return;
  }
  window.localStorage.setItem("cartState", JSON.stringify(cartState));
}, [cartState]);
mplungjan
  • 169,008
  • 28
  • 173
  • 236
Yun
  • 7
  • 4

2 Answers2

0

You are earsing the value of the local storage on the first render

useEffect(() => {
  if (initialRender.current) {
    initialRender.current = false;
    return;
  }
  //here
  window.localStorage.setItem("cartState", JSON.stringify(cartState));
}, [cartState]);

You should :

useEffect(() => {
  if (initialRender.current) {
    initialRender.current = false;
  } else {
    window.localStorage.setItem("cartState", JSON.stringify(cartState));
  }
}, [cartState]);
JeanJacquesGourdin
  • 1,496
  • 5
  • 25
0

What I usually do is have some state to check against to see if the client side is loaded:

const [clientLoaded, setClientLoaded] = useState(false);

useEffect(() => {
  setClientLoaded(true);
}, []);

Then anywhere you can check if clientLoaded is true, for example in another useEffect hook:

useEffect(() => {
  clientLoaded && doWhatever; // do whatever you want here 
}, [clientLoaded]);

Or in you render method:

{clientLoaded && <span>Render this if the client is loaded</span>}
Dirk J. Faber
  • 4,360
  • 5
  • 20
  • 58