in my understanding by default useEffect run once when the program run so when it run, the setItems change the value of items as you see :
useEffect(() => {
setItems(getCart());
}, [items]);
and when the items change useEffect again run that creates a loop, to stop it remove the dependencies.
useEffect(() => {
setItems(getCart());
}, []);