【问题标题】:TypeError: Cannot read property 'length' of undefined in Commerce JS when accessing cartTypeError:访问购物车时无法读取 Commerce JS 中未定义的属性“长度”
【发布时间】:2020-12-23 09:58:52
【问题描述】:

在 commerce js 中访问购物车对象的 line_items 数组时,我收到一条错误消息,提示它未定义,而我仍然可以在控制台中看到它。

这里是一些截图:

错误:

TypeError: Cannot read property 'length' of undefined
Cart
D:/Zayeed/Projects/e_commerce/src/components/Cart/Cart.jsx:7
   4 | 
   5 | const Cart = ({ cart }) => {
   6 |     const classes = useStyles();
>  7 |     const isEmpty = !cart.line_items.length;
   8 | 
   9 |     const EmptyCart = () => (
  10 |         <Typography variant="subtitle1">You have no items in your cart, start adding some.</Typography

我的代码:

import React from 'react'
import { Container, Typography, Button, Grid } from '@material-ui/core'
import useStyles from './styles';

const Cart = ({ cart }) => {
    const classes = useStyles();
    const isEmpty = !cart.line_items.length;

    const EmptyCart = () => (
        <Typography variant="subtitle1">You have no items in your cart, start adding some.</Typography>
    );

    const FilledCart = () => {
        <>
            <Grid container spacing={3}>
                {cart.line_items.map(item => (
                    <Grid item xs={12} sm={4} key={item.id}>
                        <div>{item.name}</div>
                    </Grid>
                ))}
            </Grid>

            <div className={classes.cardDetails}>
                    <Typography variant="h4">Subtotal: {cart.subtotal.formatted_with_symbol}</Typography>
                    <div>
                        <Button className={classes.emptyButton} size="large" type="button" variant="contained" color="secondary">Empty Cart</Button>
                        <Button className={classes.checkout} size="large" type="button" variant="contained" color="primary">Checkout</Button>
                    </div>
            </div>
        </>
    }

    return (
        <Container>
            <div className={classes.toolbar}/>
            <Typography className={classes.title} variant="h3">Your Shopping Cart:</Typography>
            {isEmpty ? <EmptyCart/> : <FilledCart />}
        </Container>
    )
}

export default Cart

购物车对象的控制台日志:

App.js:

import React, { useState, useEffect } from 'react'
import { commerce } from './lib/commerce'
import { Products, Navbar, Cart } from './components'

const App = () => {
    const [ products, setProducts ] = useState([])
    const [cart, setCart] = useState({})

    const fetchProducts = async() => {
        const { data } = await commerce.products.list()

        setProducts(data)
    }

    const fetchCart = async() => {
        setCart(await commerce.cart.retrieve())
    }

    const handleAddToCart = async(productId, quantity) => {
        const item = await commerce.cart.add(productId, quantity)

        setCart(item.cart)
    }

    useEffect(() => {
        fetchProducts()
        fetchCart()
    }, []);

    return (
        <div>
            <Navbar  totalItems={cart.total_items}/>
            {/* <Products products={products} onAddToCart={handleAddToCart}/> */}
            <Cart cart={cart}/>
        </div>
    )   
}

export default App

似乎 prop 没有按预期导入,我无法访问购物车对象的任何属性。

提前致谢!

【问题讨论】:

  • Cart 组件将在第一次渲染时调用 cart={},而访问 cart.line_items 返回 'undefined'。您必须检查 cart.line_items 是否未定义,然后必须检查其长度

标签: javascript reactjs asynchronous


【解决方案1】:

这是因为购物车内容在页面打开时没有立即从电子商务 api 加载,然后由于错误而卡住了。

您可以先检查是否有购物车内容,然后删除isEmpty变量并在javascript中编写闭包,在视频中解释了几秒钟,但经过一天的努力,我也意识到了:D

if(!cart.line_items)
    return  '...loading';


return (
    <div className={classes.toolbar}>
        <Typography className={classes.title} variant="h3"> Your Shopping Cart 
        </Typography>
        {!cart.line_items.length ? <EmptyCart /> : <FilledCart />}
       
    </div>
)

【讨论】:

    【解决方案2】:

    试试const isEmpty = Object.keys(cart).length &amp;&amp; !cart.line_items.length; 数据不是从服务器接收到的,但是组件被渲染了,这就是为什么一开始 card 是未定义的。

    【讨论】:

    • 这将帮助我显示我的购物车,但不会填充按钮
    【解决方案3】:

    尝试使用可选链:

    const isEmpty = !cart.line_items?.length

    这将仅在数组存在时询问数组长度,以防止未定义的错误。 这意味着如果cart.line_items == undefinedcart.line_items.length == 0,它将返回false。

    也许我参加聚会有点晚了,但我被困在同一部分,这解决了我的问题(而且我认为它看起来很整洁)

    【讨论】:

    • 这对我有用 - 简单的解决方案:)
    【解决方案4】:

    问题 初始渲染中没有 cart.line_items,因为初始状态是空对象 ({})。

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

    解决方案 为初始渲染提供有效的初始状态,这样就有一个真实的、已定义的 cart.line_items 对象,从中可以有一个长度属性,即 !cart.line_items.length;可以解析为一个值而不抛出错误。

    const [cart, setCart] = useState({ line_items: [] });

    【讨论】:

      猜你喜欢
      • 2021-08-05
      • 1970-01-01
      • 1970-01-01
      • 2022-09-24
      • 1970-01-01
      • 1970-01-01
      • 2020-06-12
      • 1970-01-01
      相关资源
      最近更新 更多