I used react@18
, redux
, and react-router@6
. I have a button add to cart on my product page and I want the product to be added to local storage and I have that product on my Cart page. After clicking on add to cart button I passed to Cart page with id but it shows not found. How can I solve this problem?
app.js :
<BrowserRouter>
<Routes>
<Route path="/" index element={<HomePage />} />
<Route path="/product/:id" element={<ProductPage />} />
<Route path="/cart/:id?" element={<CartPage />} />
<Route path="*" element={<NotFound />} />
</Routes>
</BrowserRouter>
cartAction.js
export const addToCart = (id) => async (dispatch, getState) => {
const { data } = await axios.get(http://localhost:8000/products/${id});
dispatch({
type: "CART_ADD_ITEM",
payload: {
id: data.id,
title: data.title,
image1: data.image1,
price: data.price,
},
});
localStorage.setItem("cartItems", JSON.stringify(getState().cart.cartItems));
};
store.js
const reducer = combineReducers({
productList: ProductListReducer,
productDetail: ProductDetailReducer,
cart: cartReducer,
});
const cartItemsFromLocalStorage = localStorage.getItem("cartItems")
? JSON.parse(localStorage.getItem("cartItems"))
: [];
const initialState = { cart: { cartItems: cartItemsFromLocalStorage } };
const middleWare = [thunk];
const store = createStore(
reducer,
initialState,
applyMiddleware(...middleWare)
);
cartReducer.js
export const cartReducer = (state = { cartItems: [] }, action) => {
switch (action.type) {
case "CART_ADD_ITEM":
const item = action.payload;
const existingItems = state.cartItems.find(
(i) => i.id === item.id
);
if (existingItems) {
return {
...state,
cartItems: state.cartItems.map((i) =>
i.id === existingItems.id ? item : i
),
};
} else {
return {
...state,
cartItems: [...state.cartItems, item],
};
}
default:
return state;
}
};
cart page:
const CartPage = () => {
const { id } = useParams();
const dispatch = useDispatch();
const cart = useSelector((state) => state.cart);
const { cartItems } = cart;
console.log(cartItems);
useEffect(() => {
if (id) {
dispatch(addToCart(id));
}
}, [dispatch, id]);
const removeCartHandler= (id) => {
dispatch(removeCart(id))
}
return (
<Container>
<Row>
<Col lg="12">
<h1>basket</h1>
{cartItems.length === 0 ? (
<p className="text-center">there is nothing in the basket</p>
) : (
<ListGroup variant="flush">
{cartItems.map((item) => {
return (
<ListGroup.Item key={item.id}>
<CartItems product={item} remove={()=>removeCartHandler(item.id)}/>
</ListGroup.Item>
);
})}
</ListGroup>
)}
</Col>
</Row>
</Container>
);
};
cart Items
const CartItems = ({product}) => {
return (
<Row>
<Col md={2}>
<Image src={product.image1} alt={product.title} fluid />
</Col>
<Col md={3}>{product.title}</Col>
<Col md={2}>{product.price}</Col>
</Row>
product page
const { id } = useParams();
const navigate = useNavigate();
const addToCartHandler = () => {
navigate(/cart/${id});
};
<Button className="btn btn-default" onClick={addToCartHandler}>
<i className="fa fa-shopping-cart"></i> Add to cart
</Button>
CodePudding user response:
Remove the trailing "?"
from the cart path. react-router-dom@6
Route
components don't take optional parameter or use regular expressions in the path
prop.
Change path="/cart/:id?"
to path="/cart/:id"
.
<BrowserRouter>
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/product/:id" element={<ProductPage />} />
<Route path="/cart/:id" element={<CartPage />} />
<Route path="*" element={<NotFound />} />
</Routes>
</BrowserRouter>