Hayaz
Hayaz

Reputation: 119

ReactJS Giving An Unexpected Warning: Each child in a list should have a unique "key" prop

It's a beautiful day but this thing is blocking my view: enter image description here

I've tried everything (except asking a question ._.) and searched everywhere. But the expected result could not be obtained :'( So, this is my code where I think the error is happening:

           <div className="mt-3">
              {data.activities?.map((act) => {
                return <Chip className="mr-2 px-3" label={act} key={act.id} />;
              })}
           </div>{" "}

Well it's a part of my file packageCard.js but if you want the whole file here it is:

import Chip from "@material-ui/core/Chip";
import Clock from "./img/main_page_icons/clock.svg";
import Person from "./img/main_page_icons/person.svg";
import MapPin from "./img/main_page_icons/map-pin.svg";
import Package1 from "./img/main_page/package 1.png";

function PackageCard({ data }) {
console.log(data);
return (
<>
  <div className="col-lg-4 col-md-6 col-sm-12 card-super-container">
    <div className="card-container">
      <div className="card-image-wrapper">
        <div>
          <div className="card-image-background">
            <img
              alt="package 1"
              src={data.featuredImg}
              style={{ borderRadius: "6px" }}
              className="w-100 "
            />
          </div>
        </div>
      </div>
      <div className="card-details-container">
        <span className="text-bold details-container-header">
          {data.name}
        </span>
        <div>
          <div className="card-details-text">
            <div>{data.description}</div>
            <div>
              <h6 className="card-price">{`Price: ${data.price} USD`}</h6>
            </div>
          </div>
        </div>
      </div>
      <div>
        <div className="card-final-desc">
          <div className="card-final-desc-item">
            <span className="card-dot"></span>
            <img alt="clock" src={Clock} className="mr-1" />
            {` ${data.days}D / ${data.nights}N `}
          </div>
          <div className="card-final-desc-item">
            <span className="card-dot"></span>
            <img alt="clock" src={Person} className="mr-1" />
            {` ${data.noOfPersons} Person `}
          </div>
          <div className="card-final-desc-item">
            <span className="card-dot"></span>
            <img alt="clock" src={MapPin} className="mr-1" />
            {` ${data.destination} `}
          </div>
        </div>
      </div>
      <div className="card-btn-container">
        <button className="btn  zoki-btn">Book Now </button>
      </div>
    </div>
  </div>

  <div className="col-lg-4 mb-4">
    <img
      alt="package 1"
      src={data.featuredImg}
      style={{ height: 250 }}
      className="w-100"
    />
    <div
      className="bg-white py-4 px-4 shadow-lg"
      style={{ fontSize: 14, textAlign: "start" }}
    >
      <h6>{data.name}</h6>
      <p>{data.description}</p>
      <div className="d-flex justify-content-between w-100">
        <h6 className="m-0">{`Price: ${data.price} USD`}</h6>
        <h6 className="m-0" style={{ color: "#9C8E35", cursor: "pointer" }}>
          Book Now
        </h6>
      </div>
      /!*{" "}
      <div className="mt-3">
        {data.activities?.map((act) => {
          return <Chip className="mr-2 px-3" label={act} key={act.id} />;
        })}
      </div>{" "}
      *!/
    </div>
    <div
      className="row shadow mx-3"
      style={{ backgroundColor: "#9C8E35", fontSize: 12 }}
    >
      <div className="col-4 p-0 text-center">
        <div
          className="py-2 text-white d-flex w-100 justify-content-center"
          style={{ borderRight: "1px solid white" }}
        >
          <img alt="clock" src={Clock} className="mr-1" />
          <p className="mb-0">{` ${data.days} D / ${data.nights} N `}</p>
        </div>
      </div>
      <div className="col-4 p-0">
        <div
          className="py-2 text-white d-flex w-100 justify-content-center"
          style={{ borderRight: "1px solid white" }}
        >
          <img alt="clock" src={Person} className="mr-1" />
          <p className="mb-0">{` ${data.noOfPersons} Person `}</p>
        </div>
      </div>
      <div className="col-4 p-0">
        <div className="py-2 text-white d-flex w-100 justify-content-center">
          <img alt="clock" src={MapPin} className="mr-1" />
          <p className="mb-0">{` ${data.destination} `}</p>
        </div>
      </div>
    </div>
  </div>
</>
 );
 }

 export default PackageCard;

Packages.js Component

import { useState, useEffect } from "react";
import { getAvailablePackages } from "crud";
import PackageBg from "../../../assets/img/offers.jpg";
import Card from "./packageCard";
import CircularProgress from "@material-ui/core/CircularProgress";
import { useHistory } from "react-router-dom";

function Packages() {
  const history = useHistory();
  const [listPackages, setListPackages] = useState([]);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    const params = {
      search: { query: "" },
      sort: "name",
      page: 1,
      pageSize: 3,
    };
    setLoading(true);
    getAvailablePackages(params)
      .then((res) => {
        // console.log(res.data.data)
        setListPackages(res.data.data.travelPackages);
        setLoading(false);
      })
      .catch((error) => {
        console.log(error.response.data);
        console.log(error.response.status);
        setLoading(false);
      });
  }, []);
  let checkData = [
    {
      name: "ahmad",
      description: "this is description",
      price: 5,
      days: 5,
      nights: 9,
      noOfPersons: 9,
      destination: "England",
      featuredImg:
        "https://media.gettyimages.com/photos/castle-combe-in-the-fall-wiltshire-england-picture-id157006201?s=612x612",
    },
    {
      name: "ali",
      description: "this is description",
      price: 5,
      days: 5,
      nights: 9,
      noOfPersons: 9,
      destination: "homeland",
      featuredImg:
        "https://images.unsplash.com/photo-1538332576228-eb5b4c4de6f5?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8ZmlubGFuZHxlbnwwfHwwfHw%3D&w=1000&q=80",
    },
    {
      name: "ali",
      description: "this is description",
      price: 5,
      days: 5,
      nights: 9,
      noOfPersons: 9,
      destination: "finland",
      featuredImg:
        "https://images.unsplash.com/photo-1538332576228-eb5b4c4de6f5?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8ZmlubGFuZHxlbnwwfHwwfHw%3D&w=1000&q=80",
    },
  ];

  return (
    <div
      id="zoki-packages"
      className="text-center py-5 my-5"
      style={{
        backgroundImage: `url(${PackageBg})`,
        backgroundPosition: "center",
        backgroundSize: "cover",
      }}
    >
      <div className="container" style={{ color: "#344767" }}>
        <h6 className="text-bold font-italic"> EXPLORE GREAT PLACES </h6>
        <h1 className=""> Popular Packages </h1>
        <div className="row justify-content-center align-content-center">
          {checkData?.map((pkg) => {
            return <Card data={pkg} key={pkg.id} />;
          })}

          {loading ? (
            <CircularProgress className="my-4 ml-auto mr-auto" />
          ) : listPackages.length ? (
            listPackages?.map((pkg) => {
              return <Card data={pkg} key={pkg.id} />;
            })
          ) : (
            <h4 className="my-4 ml-auto mr-auto">
              No Package Available at that time.
            </h4>
          )}
        </div>
        {listPackages.length ? (
          <button
            onClick={() => history.push("/search-packages")}
            className="btn btn-dark px-4 p-2 rounded-pill my-4"
            style={{ color: "#CFBD45", backgroundColor: "black", fontSize: 14 }}
          >
            <p className="mb-0"> VEIW ALL PACKAGES </p>
          </button>
        ) : null}
      </div>
    </div>
  );
}

export default Packages;

I will be very grateful if you find a solution. I appreciate any help you can provide <33

Upvotes: 0

Views: 70

Answers (2)

ThirteenD
ThirteenD

Reputation: 11

if you use the act.id as the key,should make sure every id is unique cause

Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity

here is the official docs

Upvotes: 1

Shira Nagen Hacohen
Shira Nagen Hacohen

Reputation: 21

It seems that the act does not have a unique id, try using the index of the map.

<div className="mt-3">
  {data.activities?.map((act, i) => (
    <Chip className="mr-2 px-3" label={act} key={i} />
  ))}
</div>

Upvotes: 2

Related Questions