Реагируйте: карта не является функцией пустого массива - PullRequest
0 голосов
/ 26 февраля 2020

Я пытаюсь добавить товары в корзину. Я объявил корзину пустым массивом и все еще получаю сообщение об ошибке:

TypeError: cart.map is not a function ProductContext.js:34
addItemToCart ProductContext.js:34
addItemHandler ProductCard.js:47
onClick ProductCard.js:60

Вот мой контекст:

// ProductContext.js

import React, { createContext, useState } from "react"
import { graphql, useStaticQuery } from "gatsby"

const ProductContext = createContext({
  cart: [],
  addItem: () => {}
})

const Provider = ({ children }) => {
  const [cart, setCart] = useState([]);

  const [productsList] = useState(
    useStaticQuery(
      graphql`
        query SkusForProduct {
          skus: allStripeSku(sort: { fields: [price] }) {
            edges {
              node {
                id
                currency
                price
                attributes {
                  name
                }
              }
            }
          }
        }
      `
    )
  )

  const addItemToCart = skuId => {
    let itemExisted = false
    let updatedCart = cart.map(item => {
      if (skuId === item.sku) {
        itemExisted = true
        return { sku: item.sku, quantity: ++item.quantity }
      } else {
        return item
      }
    })
    if (!itemExisted) {
      updatedCart = [...updatedCart, { sku: skuId, quantity: 1 }]
    }
    setCart({ cart: updatedCart })

    localStorage.setItem('stripe_checkout_items', JSON.stringify(updatedCart))
  }

  return (
    <ProductContext.Provider value={{ skus: productsList.skus, addItem: addItemToCart }}>
      {children}
    </ProductContext.Provider>
  )
}

export { ProductContext, Provider }

И моя ProductCard

// ProductCard.js    

import React, { useState, useContext } from "react"
import { ProductContext } from "../context/ProductContext"

const cardStyles = {
  display: "flex",
  flexDirection: "column",
  justifyContent: "space-around",
  alignItems: "flex-start",
  padding: "1rem",
  marginBottom: "1rem",
  boxShadow: "5px 5px 25px 0 rgba(46,61,73,.2)",
  backgroundColor: "#fff",
  borderRadius: "6px",
  maxWidth: "300px",
}
const buttonStyles = {
  fontSize: "13px",
  textAlign: "center",
  color: "#fff",
  outline: "none",
  padding: "12px",
  boxShadow: "2px 5px 10px rgba(0,0,0,.1)",
  backgroundColor: "rgb(255, 178, 56)",
  borderRadius: "6px",
  letterSpacing: "1.5px",
}

const formatPrice = (amount, currency) => {
  let price = (amount / 100).toFixed(2)
  let numberFormat = new Intl.NumberFormat(["en-US"], {
    style: "currency",
    currency: currency,
    currencyDisplay: "symbol",
  })
  return numberFormat.format(price)
}

const ProductCard = () => {
  const [disabled] = useState(false)
  const [buttonText, setButtonText] = useState("Add to Cart")
  const [paymentMessage, setPaymentMessage] = useState("")

  const skus = useContext(ProductContext).skus
  const addItem = useContext(ProductContext).addItem

  const addItemHandler = (event, skuId, quantity = 1) => {
    addItem(skuId);
  }


  return (
    <div>
      {skus.edges.map(({ node: sku }) => {
        return (
          <div style={cardStyles} key={sku.id}>
            <h4>{sku.attributes.name}</h4>
            <p>Price: {formatPrice(sku.price, sku.currency)}</p>
            <button
              style={buttonStyles}
              onClick={event => addItemHandler(event, sku.id)}
              disabled={disabled}
            >
              {buttonText}
            </button>
            {paymentMessage}
          </div>
        )
      })}
    </div>
  )
}

export default ProductCard

Я записал вывод корзины в функцию addItemToCart, и я получил пустой массив. Не уверен, что я сделал не так. Любая помощь будет принята с благодарностью!

1 Ответ

1 голос
/ 26 февраля 2020

Вот проблемная строка кода:

setCart({ cart: updatedCart })

После этого cart больше не будет массивом (это будет объект со свойством "cart" ", который является массивом) и поэтому не имеет функции map.

...