我正在尝试使用React Hooks创建一个购物车,该购物车保存在本地存储中,并在重新加载浏览器时得到检索。
一切都按照我想要的方式工作,但是重新加载浏览器并检索localStorage-data后,项目状态将不再更新。重新加载前后,购物车对象看起来相同。
我的购物车上下文提供程序如下:
const { itemList } = useContext(ItemContext)
const [cart, setCart] = useState(() => {
const localData =
localStorage.getItem('cart');
return localData !== null
? JSON.parse(localData)
: [];
});
console.log(cart)
useEffect(() => {
localStorage.setItem('cart', JSON.stringify(cart))
}, [cart] )
const addItem = id => {
let addedItem = itemList.find(item => item.id === id)
let addedItemExists = cart.find(item => item.id === id)
if (addedItemExists) {
addedItem.quantity += 1
setCart([...cart]);
} else {
addedItem.quantity = 1
setCart([...cart, addedItem]);
}
};
(itemList
是一个包含三项的虚拟数据列表)
我也试图通过使用reducer来解决这个问题,但是我得到了相同的结果。
我只使用React和JS几周了,所以如果这是一个noobie问题,我感到抱歉。
答案 0 :(得分:0)
像这样尝试尝试
const [cart, setCart] = useState([]);
useEffect(() => {
const localData =
localStorage.getItem('cart');
return localData !== null
? JSON.parse(localData)
: [];
}, [] )
答案 1 :(得分:0)
尝试以下方法:
ForEach(Array(ButtonsData.enumerated()), id: \.element) { i, Data in
Button(action: {
ButtonsData[i].Selected = true
ButtonsData[i].Colour = .green
}) {
Text(Data.Crit)
.font(.system(size: 30))
}
.frame(width: 65, height: 55)
.background(Data.Colour)
.cornerRadius(10)
}
或者您可以尝试:
const [cart, setCard] = useState(JSON.parse(localStorage.getItem(localData)))
然后使用:
const [cart, setCard] = useState(JSON.parse(localStorage.getItem(localData) : []))
如果您想在cart && cart.map
上进行映射,则cart
将是null
答案 2 :(得分:0)
因此,您最初是在设置购物车。 (在useState中)。尝试在useEffect中进行操作。这只是为了干净的代码。我对if-else部分进行了更改。
const { itemList } = useContext(ItemContext)
const [cart, setCart] = useState([]);
useEffect(() => {
const localData = localStorage.getItem('cart');
setCart(localData && localData.length > 0 ? JSON.parse(localData): []);
}, [])
useEffect(() => {
localStorage.setItem('cart', JSON.stringify(cart))
}, [cart] )
const addItem = id => {
let addedItem = itemList.find(item => item.id === id)
let addedItemExists = cart.find(item => item.id === id)
if (addedItemExists) {
addedItem.quantity += 1
setCart(cart => [...cart]);
} else {
addedItem.quantity = 1
setCart(cart => [...cart, addedItem]);
}
};
答案 3 :(得分:0)
您只是在useState
内部传递了一个函数,而没有对其进行了调用
只需调用该函数即可。
const { itemList } = useContext(ItemContext);
const initialStateFun = () => {
const localData = localStorage.getItem("cart");
return localData !== null ? JSON.parse(localData) : [];
}
const [cart, setCart] = useState(initialStateFun()); //<--- call the fun
console.log(cart);
...
此外,如果您想变得更简单,则只需使用三元
useState(localStorage.getItem('cart') !== null ? JSON.parse(localData) : []);
答案 4 :(得分:0)
要部分更新状态时,需要使用setState
的第一个参数,代表先前的状态
setCart((prev) => ([...prev]));
...
setCart((prev) => ([...prev, addedItems]));
而不是使用其当前值。
现在,在addItem
为addedItemExists
的情况下,您的true
函数看起来有问题,您似乎并没有更新本地状态,而是itemList
(您只更新了{ {1}}及其当前值。
也许您应该尝试以下方法:
cart