React:未捕获类型错误:items.map不是函数



当我单击某个按钮重定向到页面时,页面没有显示内容。

当我选中View=>开发者=>开发人员工具=>控制台,它显示错误文本如下:

未捕获的类型错误:items.map不是函数在ShoppingCart.js:6:1

在mountMemo(react-dom.development.js:15846:1(

在Object.useMemo(react-dom.development.js:16219:1(

在useMemo(react.development.js:1532:1(

在购物车(ShoppingCart.js:6:1(

在renderWithHooks(react-dom.development.js:14985:1(

在mountIndeterminateComponent(react-dom.development.js:1781:1(

在beginWork(react-dom.development.js:19049:1(

在HTMLUnknownElement.callCallback(react-dom.development.js:3945:1(

在Object.invokeGuardedCallbackDev(react-dom.development.js:3994:1(

上述错误发生在组件中:

at ShoppingCart (http://localhost:3000/static/js/bundle.js:1063:68)
at div
at http://localhost:3000/static/js/bundle.js:20449:23
at div
at http://localhost:3000/static/js/bundle.js:23024:23
at div
at http://localhost:3000/static/js/bundle.js:20648:23
at Menu (http://localhost:3000/static/js/bundle.js:2709:76)
at Route (http://localhost:3000/static/js/bundle.js:184334:29)
at Switch (http://localhost:3000/static/js/bundle.js:184536:29)
at Router (http://localhost:3000/static/js/bundle.js:183969:30)
at BrowserRouter (http://localhost:3000/static/js/bundle.js:183590:35)
at AuthProvider (http://localhost:3000/static/js/bundle.js:1962:5)
at App

考虑在树中添加一个错误边界,以自定义错误处理行为。参观https://reactjs.org/link/error-boundaries以了解有关错误边界的更多信息。

开发人员工具中的错误消息

开发者工具1 中的错误消息

Developer Tools 1 中的错误消息

import { IoCloseOutline } from 'react-icons/io5';
import { useParams } from 'react-router-dom';
import React, { useState, useEffect, useMemo } from 'react';
import { fetchPlace } from '../apis';
import styled from 'styled-components';
import MenuList from '../components/MenuList';
import ShoppingCart from '../components/ShoppingCart';
const OrderButton = styled(Button)`
position: fixed;
bottom: 20px;
right: 20px;
border-radius: 50%;
box-shadow: 1px 1px 8px rgba(0,0,0,0.2);
width: 60px;
height: 60px;
`;
const Menu = () => {
const [place, setPlace] = useState({});
const [shoppingCart, setShoppingCart] = useState({});
const [showShoppingCart, setShowShoppingCart] = useState(false);
const params = useParams();
const onFetchPlace = async () => {
const json = await fetchPlace(params.id);
console.log(json);
if (json) {
setPlace(json);
}
};
const onAddItemtoShoppingCart = (item) => {
setShoppingCart({
...shoppingCart,
[item.id]: {
...item,
quantity: (shoppingCart[item.id]?.quantity || 0) + 1,
}
});
}
const onRemoveItemToShoppingCart = (item) => {
if (totalQuantity === 1) {
setShowShoppingCart(false);
}
setShoppingCart({
...shoppingCart,
[item.id]: {
...item,
quantity: (shoppingCart[item.id]?.quantity || 0) - 1,
}
});
}
const totalQuantity= useMemo(
() => Object.keys(shoppingCart)
.map((i) => shoppingCart[i].quantity)
.reduce((a,b) => a + b, 0),
[shoppingCart] 
);
useEffect(() => {
onFetchPlace();
}, []);
return (
<Container className="mt-5 mb-5">
<Row className="justify-content-center">
<Col lg={8}>
{showShoppingCart ? (
<ShoppingCart 
items={Object.keys(shoppingCart)
.map((key) => shoppingCart[key])
.filter((item) => item.quantity > 0)
}
onAdd={onAddItemtoShoppingCart}
onRemove={onRemoveItemToShoppingCart}
/>
) : (
<MenuList 
place={place} 
shoppingCart={shoppingCart} 
onOrder={onAddItemtoShoppingCart} 
/>
)}

</Col>
</Row>
{totalQuantity ? (
<OrderButton variant="standard" onClick={() => setShowShoppingCart(!showShoppingCart)}>
{showShoppingCart ? <IoCloseOutline size={25} /> : totalQuantity}
</OrderButton>
) : null}
</Container>
)
};
export default Menu;

购物车代码(错误发生的地方(

import { Card } from 'react-bootstrap';
import OperationButton from './OperationButton';
const ShoppingCart = ( items, onAdd, onRemove ) => {
const totalPrice = useMemo(
() => items.map((i) => i.quantity * i.price).reduce((a,b) => a + b, 0),
[items]
);
return (
<>
<h3 className="text-center mb-4">
<b>Your Order</b>
</h3>
<Card>
<Card.Body>
{items.map((item) => (
<div key={item.id} className="d-flex mb-4 align-items-center">
<div className="flex-grow-1">
<p className="mb-0">
<b>{item.name}</b>
</p>
<span>${item.price}</span>
</div>
<div className="d-flex align-items-center">
<OperationButton
variant="lightgray"
size="sm"
onClick={() => onRemove(item)}
>    
-
</OperationButton>
<span>{item.quantity}</span>
<OperationButton
variant="lightgray"
size="sm"
onClick={() => onAdd(item)}

>    
+
</OperationButton>
</div>
</div>
))}
<hr/>
<div className="d-flex justify-content-between">
<h5><b>Total</b></h5>
<h5><b>{totalPrice}</b></h5>
</div>
</Card.Body>
</Card>
</>
);
};
export default ShoppingCart;

我的包.json

"version": "0.1.0",
"private": true,
"proxy": "http://localhost:8000",
"dependencies": {
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"bootstrap": "^4.6.0",
"qrcode.react": "^3.1.0",
"react": "^17.0.2",
"react-bootstrap": "^1.5.2",
"react-dom": "^17.0.2",
"react-dropzone": "^11.3.2",
"react-icons": "^4.2.0",
"react-router-dom": "^5.2.0",
"react-scripts": "^5.0.1",
"react-to-print": "^2.14.7",
"react-toastify": "^7.0.3",
"styled-components": "^5.2.3",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

这是页面这是页面

在该页面中;添加到购物车";按钮,一个订单按钮将出现在页面的右下方。之后,当我点击订单按钮时,它将指向一个页面,并假设它会显示这样。

点击订单按钮后(不是我的

然而,对我来说,这并没有显示什么。我的页面点击订单按钮后

有人能告诉我如何解决吗?

const ShoppingCart = ( items, onAdd, onRemove ) => {不是访问道具值的方式。该组件有一个参数(props(,而不是三个参数。

所以您刚刚将props命名为items,这是一个对象,对象上没有像数组一样的map。下次添加控制台登录以查看items是什么。

你想做的是破坏道具对象:

const ShoppingCart = ({ items, onAdd, onRemove }) => {

您的ShoppingCart组件声明不正确。函数组件只接收一个参数,即props对象。

您可以像这样破坏prop参数:

const ShoppingCart = ({ items, onAdd, onRemove }) => {
//...

对不起,还没有阅读完整的问题。但您应该始终检查数组是否有长度(这意味着它是否有一些值(。

items?.length && items.map()

项目?。length将确保数组是否存在并且具有一定的长度。

你也可以使用类似的东西:

items?.length ? items.map() : 'no data found'

最新更新