Whilst I am doing cart in react, I have no idea why I keep getting NaN value – only from a specific object data.
When I have the following data list:
#1 ItemsList.js
export const ItemsList = [ { id: 1, name: "VA-11 Hall-A: Cyberpunk Bartender Action", price: 110000, image: cover1, link: "https://store.steampowered.com/app/447530/VA11_HallA_Cyberpunk_Bartender_Action/?l=koreana", }, ... { id: 6, name: "Limbus Company", price: 110000, image: cover6, link: "https://limbuscompany.com/", }, ];
And the following code, please look at the comment line.
#2 Goods.jsx
import React, { useContext } from "react"; import "./Goods.css"; import { DataContext } from "../../components/context/DataContext"; export const Goods = (props) => { const { id, name, price, image, link } = props.shopItemProps; const { cartItems, addItemToCart, removeItemFromCart } = useContext(DataContext); const cartItemStored = cartItems[id]; return ( <div className="goods"> <div className="goods-id">{id}</div> <img src={image} alt="thumbnail_image" className="goods-image" /> <div className="goods-name">{name}</div> <div className="goods-price">${price}</div> <button> <a href={link} className="goods-link"> Official Store Page </a> </button> <div className="cart-button"> <button onClick={() => removeItemFromCart(id)}>-</button> // ★Maybe here? but why do I get NaN only for id:6? Others work well. {cartItemStored > -1 && <> ({cartItemStored}) </>} <button onClick={() => addItemToCart(id)}>+</button> </div> </div> ); };
What should I do to solve NaN? There seems to be no way to make that value as int in this case. Or do you see any problem from the above code block?
Edited
Sorry for confusing you. Here are the additional code related.
#3. DataContext.js (where cartItems state exists)
import React, { createContext, useState } from "react"; import { ItemsList } from "../ItemsList"; export const DataContext = createContext(null); const getDefaultCart = () => { let cart = {}; for (let i = 1; i < ItemsList.length; i++) { cart[i] = 0; } return cart; }; export const DataContextProvider = (props) => { const [cartItems, setCartItems] = useState(getDefaultCart); const checkoutTotalSum = () => { let totalAmount = 0; for (const item in cartItems) { if (cartItems[item] > 0) { let itemInfo = ItemsList.find((product) => product.id === Number(item)); totalAmount += cartItems[item] * itemInfo.price; } } return totalAmount; }; const addItemToCart = (itemId) => { setCartItems((prev) => ({ ...prev, [itemId]: prev[itemId] + 1 })); }; const removeItemFromCart = (itemId) => { setCartItems((prev) => ({ ...prev, [itemId]: prev[itemId] - 1 })); }; const updateCartItemCount = (newAmount, itemId) => { setCartItems((prev) => ({ ...prev, [itemId]: newAmount })); }; const contextValue = { cartItems, addItemToCart, removeItemFromCart, updateCartItemCount, checkoutTotalSum, }; // console.log(cartItems); return ( <DataContext.Provider value={contextValue}> {props.children} </DataContext.Provider> ); };
Advertisement
Answer
The issue is in the function you are using to set the initial value of cartItems
, more specifically, in the for
loop. This line is the culprit: i < ItemsList.length
, when in your case, it should be i <= ItemsList.length
. Why? because you are not including the last element of ItemsList
on the cart
object (you are initializing the i
counter with 1 and ItemsList
‘s length is 6).
So, when you call addItemToCart
:
const addItemToCart = (itemId) => { setCartItems((prev) => ({ ...prev, [itemId]: prev[itemId] + 1 })); };
And try to update the value corresponding to the last element of ItemsList
which is 6 in cartItems
, you’re getting: '6': undefined + 1
because again, you did skip the last element in the for
loop. This results in NaN
.
You also have the option of initializing i
with 0 and preserve this line: i < ItemsList.length
, or:
for (let i = 1; i < ItemsList.length + 1; i++) { ... }