0

so I've been having this issue with my web page that im unable to solve on my own. Everything works, however when I add Items to my cart instead of aadding the item it replaces the current item with that one. When I go to inspect my CartScreen it displays this error: react-jsx-dev-runtime.development.js:87 Warning: Each child in a list should have a unique "key" prop.

Check the render method of CartScreen. See https://reactjs.org/link/warning-keys for more information. i dont get it because I assumed that I hve a unquie key prop at Line:54 I need help if anyone knows the issue here. Here is my CartScreen code: `

import { useContext } from 'react';
import { Store } from '../Store';
import { Helmet } from 'react-helmet-async';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
import MessageBox from '../components/MessageBox';
import ListGroup from 'react-bootstrap/ListGroup';
import Button from 'react-bootstrap/Button';
import Card from 'react-bootstrap/Card';
import { Link, useNavigate } from 'react-router-dom';
import axios from 'axios';

export default function CartScreen() {
  const navigate = useNavigate();
  const { state, dispatch: ctxDispatch } = useContext(Store);
  const {
    cart: { cartItems },
  } = state;

  const updateCartHandler = async (item, quantity) => {
    const { data } = await axios.get(`/api/products/${item._id}`);
    if (data.countInStock < quantity) {
      window.alert('Sorry. Product is out of stock');
      return;
    }
    ctxDispatch({
      type: 'CART_ADD_ITEM',
      payload: { ...item, quantity },
    });
  };
  const removeItemHandler = (item) => {
    ctxDispatch({ type: 'CART_REMOVE_ITEM', payload: item });
  };

  const checkoutHandler = () => {
    navigate('/signin?redirect=/shipping');
  };

  return (
    <div>
      <Helmet>
        <title>Shopping Cart</title>
      </Helmet>
      <h1>Shopping Cart</h1>
      <Row>
        <Col md={8}>
          {cartItems.length === 0 ? (
            <MessageBox>
              Cart is empty. <Link to="/">Go Shopping</Link>
            </MessageBox>
          ) : (
            <ListGroup>
              {cartItems.map((item) => (
The key is right here:
                <ListGroup.Item key={item._id}>
                  <Row className="align-items-center">
                    <Col md={4}>
                      <img
                        src={item.image}
                        alt={item.name}
                        className="img-fluid rounded img-thumbnail"
                      ></img>{' '}
                      <Link to={`/product/${item.slug}`}>{item.name}</Link>
                    </Col>
                    <Col md={3}>
                      <Button
                        onClick={() =>
                          updateCartHandler(item, item.quantity - 1)
                        }
                        variant="light"
                        disabled={item.quantity === 1}
                      >
                        <i className="fas fa-minus-circle"></i>
                      </Button>{' '}
                      <span>{item.quantity}</span>{' '}
                      <Button
                        variant="light"
                        onClick={() =>
                          updateCartHandler(item, item.quantity + 1)
                        }
                        disabled={item.quantity === item.countInStock}
                      >
                        <i className="fas fa-plus-circle"></i>
                      </Button>
                    </Col>
                    <Col md={3}>${item.price}</Col>
                    <Col md={2}>
                      <Button
                        onClick={() => removeItemHandler(item)}
                        variant="light"
                      >
                        <i className="fas fa-trash"></i>
                      </Button>
                    </Col>
                  </Row>
                </ListGroup.Item>
              ))}
            </ListGroup>
          )}
        </Col>
        <Col md={4}>
          <Card>
            <Card.Body>
              <ListGroup variant="flush">
                <ListGroup.Item>
                  <h3>
                    Subtotal ({cartItems.reduce((a, c) => a + c.quantity, 0)}{' '}
                    items) : $
                    {cartItems.reduce((a, c) => a + c.price * c.quantity, 0)}
                  </h3>
                </ListGroup.Item>
                <ListGroup.Item>
                  <div className="d-grid">
                    <Button
                      type="button"
                      variant="primary"
                      onClick={checkoutHandler}
                      disabled={cartItems.length === 0}
                    >
                      Proceed to Checkout
                    </Button>
                  </div>
                </ListGroup.Item>
              </ListGroup>
            </Card.Body>
          </Card>
        </Col>
      </Row>
    </div>
  );
}

Actually I attempted to follow the instructions from the reactjs.org website on lists-and-keys but it was unsuccessful and I really didnt know how to go about it.

Dave2K
  • 19
  • 4
  • at a glance this looks OK as far as the `key` is concerned. Are you sure that all the `item._id` properties in your data are actually unique? (We can't possibly tell that from the code you've shown.) – Robin Zigmond Feb 15 '23 at 22:28
  • Does [this](https://stackoverflow.com/questions/34576332/warning-each-child-in-an-array-or-iterator-should-have-a-unique-key-prop-che) answers your question? – Amr Feb 15 '23 at 22:29
  • For my data _id: is set to a string starting from '1' and then increasing numerically for each product. I solved the issue regarding the error however the functionality of the CartScreen is still giving me problems. I want it to function like any other website where you can add multiple items to the cart. Instead of adding various items, it replaces the current item. Any ideas? – Dave2K Feb 16 '23 at 01:15

1 Answers1

0

You've got duplicate ids. change it to cartItems.map((item, i) => ...) and use i for the key.

pguardiario
  • 53,827
  • 19
  • 119
  • 159
  • Thanks! This did get rid of the error, however, I'm still having a functionality issue. When I add items to the cart instead of that item being added, it just replaces the other one. – Dave2K Feb 16 '23 at 01:09
  • I can't go into that too much but it should look something like: `onClick={() => setCartItems([...cartItems, item])}` – pguardiario Feb 16 '23 at 01:14
  • Ok, I know you said you can't really go into that but where would I might add that? I have onClicks for my increase /decrease quantity buttons, and one for removeItemHanlder, but where would I add that? – Dave2K Feb 16 '23 at 01:21
  • to the add to cart button, but that would require you to redo your cart to make it simpler – pguardiario Feb 16 '23 at 01:42
  • ok thats fine. I actually posted another more in-depth question https://stackoverflow.com/questions/75467086/im-unable-to-add-multiple-items-to-my-cart – Dave2K Feb 16 '23 at 01:52