我正在尝试使用 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
是一个包含三个项目的虚拟数据列表(
我也尝试通过使用减速器来解决此问题,但我得到了相同的结果。
我只使用 React 和 JS 几个星期,所以如果这是一个菜鸟问题,我很抱歉。
当你想部分更新你的状态时,你需要使用setState
的第一个参数,表示之前的状态
setCart((prev) => ([...prev]));
...
setCart((prev) => ([...prev, addedItems]));
而不是使用其当前值。
现在,您的addItem
函数看起来有问题,以防万一addedItemExists
true
,您似乎没有更新本地状态,而是itemList
(您只需使用其当前值更新cart
(。
也许您应该尝试以下方法:
const addItem = (id) => {
const addedItem = itemList.find(item => item.id === id);
const addedItemExists = cart.some(item => item.id === id);
if (addedItemExists) {
setCart((prev) => prev.map((item) => (
item.id === id
? { ...item, quantity: item.quantity + 1 }
: item
)));
} else {
setCart((prev) => ([ ...prev, { ...addedItem, quantity: 1 } ]));
}
}
尝试这样
做const [cart, setCart] = useState([]);
useEffect(() => {
const localData =
localStorage.getItem('cart');
return localData !== null
? JSON.parse(localData)
: [];
}, [] )
试试这个:
const [cart, setCard] = useState(JSON.parse(localStorage.getItem(localData)))
或者您可以尝试:
const [cart, setCard] = useState(JSON.parse(localStorage.getItem(localData) : []))
然后使用:
cart && cart.map
当您想映射它时,如果localStorage
中不存在,则将cart
null
因此,您最初正在设置购物车。(在使用状态中(。尝试在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]);
}
};
你只是在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) : []);