简体   繁体   中英

Each child in a list should have a unique "key" prop Error for custom component

I am mapping over an array and rendering a custom card component for each index in the array. However, I am receiving the error "Each child in a list should have a unique "key" prop" 1 . Although, I am passing the index as the key. I have tried with a React.fragment and passing the index down to the card component and adding the key there. Both methods are still throwing the same error.

Main Component

import React from "react";
import { useRouter } from "next/router";
import { Button, Container } from "@mui/material";
import { makeStyles } from "@mui/styles";
import { InstructionsCard } from "../layout/directory";
import {
  RiNumber1 as OneIcon,
  RiNumber2 as TwoIcon,
  RiNumber3 as ThreeIcon,
} from "react-icons/ri";

function InstructionSection() {
  const router = useRouter();
  const classes = useStyles();

  const instructions = [
    {
      id: 1,
      icon: OneIcon,
      title: "step one",
      text: [
        "Navigate to the",
        <Button
          onClick={() => router.push("/requirements")}
          size="small"
          style={{ margin: "5px" }}
          variant="outlined"
          color="inherit"
        >
          requirements
        </Button>,
        "page for our most frequently asked questions and specific requirements before booking any activity. ",
      ],
    },
    {
      id: 2,
      icon: TwoIcon,
      title: "step two",
      text: [
        "Find the activity you are interested in and read through the information carefully. Be sure to fully understand the,",
        <Button
          onClick={() => router.push("/#upgrades")}
          size="small"
          style={{ margin: "5px" }}
          variant="outlined"
          color="inherit"
        >
          entry fee
        </Button>,
        " and",
        <Button
          onClick={() => router.push("/#upgrades")}
          size="small"
          style={{ margin: "5px" }}
          variant="outlined"
          color="inherit"
        >
          upgrade
        </Button>,
        " packages",
      ],
    },
    {
      id: 3,
      icon: ThreeIcon,
      title: "step three",
      text: [
        "Please, be sure to verify we are ",
        <Button
          onClick={() => router.push("/locations")}
          size="small"
          style={{ margin: "5px" }}
          variant="outlined"
          color="inherit"
        >
          located
        </Button>,
        " in your area. Select an experience, date, time-slot, toggle any upgrades, and continue through checkout.",
      ],
    },
  ];

  return (
    <Container className={classes.root}>
      {/* instructions iteration */}
      {instructions.map((_instruction, index) => {
        return (
          <React.Fragment key={index}>
            <InstructionsCard item={_instruction} />
          </React.Fragment>
        );
      })}
    </Container>
  );
}

// custom styles
const useStyles = makeStyles((theme) => ({
  root: {
    [theme.breakpoints.down("md")]: {
      flexDirection: "column",
    },
    width: "100%",
    display: "flex",
    justifyContent: "space-evenly",
  },
}));

export default InstructionSection;

Card Component

import { makeStyles } from "@mui/styles";
import { Card, CardContent, Typography, Divider } from "@mui/material";

const InstructionsCard = ({ item }) => {
  const classes = useStyles();
  const Icon = item.icon;

  return (
    <Card className={classes.root}>
      <CardContent>
        <Icon className={classes.icon} />
        <Typography className={classes.title} variant="h5" component="h6">
          {item.title.toUpperCase()}
        </Typography>
        <Divider className={classes.divider} />
        <Typography
          variant="subtitle1"
          component="p"
          sx={{ mb: 1.5 }}
          color="text.secondary"
        >
          {item.text}
        </Typography>
      </CardContent>
    </Card>
  );
};

const useStyles = makeStyles((theme) => ({
  root: {
    [theme.breakpoints.down("md")]: {
      margin: theme.spacing(4, 0, 4, 0),
    },
    background: theme.palette.primary.main,
    borderRadius: theme.spacing(5),
    padding: theme.spacing(2),
    margin: theme.spacing(5),
    width: "100%",
    textAlign: "center",
    boxShadow: `0px 0px 10px 10px ${theme.palette.offset.main}`,
  },
  icon: {
    background: theme.palette.secondary.dark,
    width: "50px",
    height: "50px",
    padding: "15px",
    borderRadius: theme.spacing(5),
  },
  divider: {
    background: theme.palette.secondary.dark,
    padding: "2px",
    width: "20%",
    margin: theme.spacing(1, "auto", 1, "auto"),
  },
  title: {
    fontWeight: 800,
  },
}));

export default InstructionsCard;

Change like this in your main component

React.Fragment we need to use One time it can't use multiple time

return (
    <Container className={classes.root}>
      <React.Fragment>
        {instructions.map((_instruction, index) => {
          <InstructionsCard key={index} item={_instruction} />;
        })}
      </React.Fragment>
    </Container>
  );

Thank You

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM