Home > other >  REACT: Warning: Received NaN for the `children` attribute. If this is expected, cast the value to a
REACT: Warning: Received NaN for the `children` attribute. If this is expected, cast the value to a

Time:02-17

I need to use a quantity for my cart, I'm learning react, but I get this warning: Warning: Received NaN for the children attribute. If this is expected, cast the value to a string.

import { createContext, useState, useContext, useEffect } from "react";

export const CartContext = createContext([]);

export const CartProvider = ({children}) => {

    const [cart, setCart] = useState([]);
    //const cantidadProductos = cart.length;


    const [cartQuantity, setCartQuantity] = useState(0);

    useEffect(() => {
        const getQuantity = () => {
            let cantidadTotalProductos = 0;
            cart.forEach((orden)=>{
                cantidadTotalProductos  = Number(orden.cantidadTotalProductos);
            });
            setCartQuantity(cantidadTotalProductos);
        }
        getQuantity();
    }, [cart]);



    const addItem = (item, cantidad) => {
        const newItem = { item, cantidad };
        const itemEsta = cart.find((order) => order.item.id === item.id);

        if(itemEsta){
            const actualizarCarrito = cart.map((order) => {
                if(order.item.id === item.id){
                    return {...order, cantidad: cantidad   order.cantidad};
                }else{
                    return order;
                }
            });
            setCart(actualizarCarrito);
        }else{
            setCart((prevState) => [...prevState, newItem]);
        }
    };

    const removeItem = (id) => {
        setCart((prev) => prev.filter((element) => element.item.id !== id));
    };

    const clearAll = () => {
        setCart([]);
    };


    return (
        <CartContext.Provider value={{ cart, addItem, removeItem, clearAll, cartQuantity }}>
            {children}
        </CartContext.Provider>
    );
};

export const useCart = () => useContext(CartContext);

And then in the component:

import './Carrito.css';
import { useCart } from "../context/CartContext";

function Carrito () {

    const { cartQuantity } = useCart();
    return <div className="editarCarrito">
        <p className="carritoCantidad">{ cartQuantity }</p>
    </div>
        
}

export default Carrito;

CodePudding user response:

Issue

The code is doing an arithmetic operation with a non-number type, and once this occurs the result is Nan and by definition any further arithmetic operations also always result in NaN.

useEffect(() => {
  const getQuantity = () => {
    let cantidadTotalProductos = 0;
    cart.forEach((orden)=>{
      cantidadTotalProductos  = Number(orden.cantidadTotalProductos); // <-- cantidadTotalProductos is undefined
    });
    setCartQuantity(cantidadTotalProductos);
  }
  getQuantity();
}, [cart]);

const addItem = (item, cantidad) => {
  const newItem = { item, cantidad }; // <-- no cantidadTotalProductos property
  const itemEsta = cart.find((order) => order.item.id === item.id);

  if (itemEsta) {
    const actualizarCarrito = cart.map((order) => {
      if (order.item.id === item.id) {
        return { ...order, cantidad: cantidad   order.cantidad };
      } else {
        return order;
      }
    });
    setCart(actualizarCarrito);
  } else {
    setCart((prevState) => [...prevState, newItem]);
  }
};

Solution

I think cantidad is the quantity value you are wanting to sum over. Provide a fallback value in case Number(cantidad) isn't a number.

useEffect(() => {
  const cantidadTotalProductos = cart.reduce(
    (total, { cantidad }) => total   (Number(cantidad) || 0),
    0
  );
  setCartQuantity(cantidadTotalProductos);
}, [cart]);

Suggestion

The cart item total quantity is what is considered derived state since it's easily computable from the actual cart state, and really shouldn't also be stored in state. Compute it in the render result as part of the context value.

Identify The Minimal (but complete) Representation of UI State

Let’s go through each one and figure out which one is state. Ask three questions about each piece of data:

  1. Is it passed in from a parent via props? If so, it probably isn’t state.
  2. Does it remain unchanged over time? If so, it probably isn’t state.
  3. Can you compute it based on any other state or props in your component? If so, it isn’t state.

Example:

const cartQuantity = cart.reduce(
  (total, { cantidad }) => total   (Number(cantidad) || 0),
  0
);

return (
  <CartContext.Provider
    value={{ cart, addItem, removeItem, clearAll, cartQuantity }}
  >
    {children}
  </CartContext.Provider>
);
  • Related