When I click the certain button to redirect to the page, the page did not show the content.
When I checked View => Developer => Developer Tools => console, it shows errors text below:
Uncaught TypeError: items.map is not a function at ShoppingCart.js:6:1
at mountMemo (react-dom.development.js:15846:1)
at Object.useMemo (react-dom.development.js:16219:1)
at useMemo (react.development.js:1532:1)
at ShoppingCart (ShoppingCart.js:6:1)
at renderWithHooks (react-dom.development.js:14985:1)
at mountIndeterminateComponent (react-dom.development.js:17811:1)
at beginWork (react-dom.development.js:19049:1)
at HTMLUnknownElement.callCallback (react-dom.development.js:3945:1)
at Object.invokeGuardedCallbackDev (react-dom.development.js:3994:1)
The above error occurred in the component:
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
Consider adding an error boundary to your tree to customize error handling behavior. Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.
Errors messages in Developer Tools
Error message in Developer Tools 1
rror message in 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;
Shopping Cart Code(Where the errors happened)
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;
My package.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"
]
}
}
This is the page This is the page
In this page, after I click the "Add to shopping cart" button, one order button will be appeared at the right bottom of the page. After that, when I click the order button it will direct to a page and supposed it will shows like that.
After click order button(Not mine
However, for mine, it shows nothing. My page after click order button
Can anyone tell me how to resolve it?
CodePudding user response:
const ShoppingCart = ( items, onAdd, onRemove ) => {
is not how you access the prop values. The component has one argument (props) not three arguments.
So you have just named props items
which is an object, objects don't have map
on them like arrays. Next time add a console log in to see what items
is.
What you meant to do is destructure the props object:
const ShoppingCart = ({ items, onAdd, onRemove }) => {
CodePudding user response:
Your ShoppingCart
component declaration is not right. Function components receive one argument only, the props
object.
You can destruct the prop
argument like this:
const ShoppingCart = ({ items, onAdd, onRemove }) => {
//...
CodePudding user response:
sorry, haven't read the full question. but you should always check if the array has length or not (which means it has some value or not).
items?.length && items.map()
items?.length will make sure if the array exists and has some length.
also you can use something like:
items?.length ? items.map() : 'no data found'