【问题标题】:Fix " unique 'key' prop" error while using React fragments [duplicate]修复使用 React 片段时的“唯一'key'prop”错误[重复]
【发布时间】:2021-01-01 08:01:12
【问题描述】:

我不断收到“警告:列表中的每个孩子都应该有一个唯一的‘键’道具。”控制台中的错误。经过一番检查,我发现需要为每个孩子以及孩子中的每个元素提供一个密钥。我已在地图功能中的 Grid、Link 和 Card 组件中添加了键,但错误仍然存​​在。 Card 组件的子组件是否也需要密钥?因为我认为我没有足够的唯一键。还是我将密钥添加到错误的组件?请帮忙。

export default function CourseCards() {
  const classes = useStyles();
  const [anchorEl, setAnchorEl] = React.useState(null);

  const handlePopoverOpen = (event) => {
    setAnchorEl(event.currentTarget);
  };

  const handlePopoverClose = () => {
    setAnchorEl(null);
  };

  const open = Boolean(anchorEl);

  // COURSE CARDS DATA
  const courseData = [
    {
      title: "Data Science  >",
      description: "Machine Learning bootcamp",
      price: "$236",
      rating: "",
      url: "/",
      img:
        "https://uploads.codesandbox.io/uploads/user/1/skny-12.jpg"
    },
    {
      title: "ApacheBlaBla >",
      description: "Coding and Basics",
      price: "",
      rating: "",
      url: "/",
      img:
        "https://uploads.codesandbox.io/uploads/user/2/e-7V-11.jpg"
    },
    {
      title: "temporary",
      description: "Testing",
      price: "",
      rating: "",
      url: "/",
      img:
        "https://uploads.codesandbox.io/uploads/user/42/Nmwx-16.jpg"
    },
    {
      title: "",
      description: "Great",
      price: "Free",
      rating: "",
      url: "/",
      img:
        "https://uploads.codesandbox.io/uploads/user/12/iiVp15.jpg"
    },
    {
      title: "Java >",
      description: "Engine Creating for PS4",
      price: "$20",
      rating: "",
      url: "/",
      img:
        "https://uploads.codesandbox.io/uploads/user/2/S0J2-13.jpg"
    },
    {
      title: "App Development >",
      description: " Developments Basics",
      price: "$30",
      rating: "",
      url: "/",
      img:
        "https://uploads.codesandbox.io/uploads/user/142/gV14.jpg"
    }
  ];

//MAPPING FUNCTION
  const courseCards = courseData.map((course, index) => (
    <>
      <Grid key={course.description} item xs={12} sm={4}>
        <Link key={course.title+index} to={course.url} className={classes.link}>
          <Card
            key={course.img}
            style={{
              maxWidth: 345,
              height: "100%",
              paddingBottom: 32,
              borderRadius: 0
            }}
          >
            <CardActionArea>
              <CardMedia
                style={{ height: 140 }}
                image={course.img}
                title={course.title}
              />
              <CardHeader
                action={
                  <IconButton
                    aria-label="more"
                    aria-owns={open ? "mouse-over-popover" : undefined}
                    aria-haspopup="true"
                    onMouseEnter={handlePopoverOpen}
                    onMouseLeave={handlePopoverClose}
                  >
                    <MoreVertIcon />
                  </IconButton>
                }
              />
              <CardContent>
                <Typography
                  gutterBottom
                  variant="body2"
                  color="textSecondary"
                  component="p"
                >
                  {course.title}
                </Typography>
                <Typography variant="h6" component="h2">
                  {course.description}
                </Typography>
              </CardContent>
            </CardActionArea>
            <CardActions
              style={{
                display: "flex",
                flexDirection: "row",
                justifyContent: "space-between"
              }}
            >
              <Button size="small" color="primary">
                {course.rating}
              </Button>
              <Button size="small" color="primary">
                {course.price}
              </Button>
            </CardActions>
          </Card>
        </Link>
      </Grid>

      <Popover
        id="mouse-over-popover"
        className={classes.popover}
        classes={{
          paper: classes.paper
        }}
        open={open}
        anchorEl={anchorEl}
        anchorOrigin={{
          vertical: "center",
          horizontal: "center"
        }}
        transformOrigin={{
          vertical: "center",
          horizontal: "right"
        }}
        onClose={handlePopoverClose}
        disableRestoreFocus
      >
        {/* POPOVER CARDS */}
        <CoursePopoverCards title={course.title} />
      </Popover>
    </>
  ));

  return (
    <div>
      <Container className={classes.container}>
        <Grid
          container
          direction="row"
          justify="space-around"
          alignItems="stretch"
          spacing={3}
        >
          {courseCards}
        </Grid>
        <Grid
          container
          direction="row"
          justify="center"
          className={classes.showBtnBox}
        >
          <Button
            variant="contained"
            className={classes.showBtn}
            color="primary"
            size="large"
          >
            Show All
          </Button>
        </Grid>
      </Container>
    </div>
  );
}

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    不是为子(列表)中的每个Element,您应该将键添加到列表的根元素。只需用Fragment 包装列表元素,为其添加键。

    const courseCards = courseData.map((course, index) => (
        <React.Fragemnt key={course.title+index}>
          <Grid item xs={12} sm={4}>
            <Link to={course.url} className={classes.link}>
              <Card
                key={course.img}
                style={{
                  maxWidth: 345,
                  height: "100%",
                  paddingBottom: 32,
                  borderRadius: 0
                }}
              >
               // Stuff
              </Card>
            </Link>
          </Grid>
    
          <Popover
            id="mouse-over-popover"
            className={classes.popover}
            classes={{
              paper: classes.paper
            }}
            open={open}
            anchorEl={anchorEl}
            anchorOrigin={{
              vertical: "center",
              horizontal: "center"
            }}
            transformOrigin={{
              vertical: "center",
              horizontal: "right"
            }}
            onClose={handlePopoverClose}
            disableRestoreFocus
          >
            {/* POPOVER CARDS */}
            <CoursePopoverCards title={course.title} />
          </Popover>
        </React.Fragment>
      ));
    

    【讨论】:

      【解决方案2】:

      您应该将key 分配给 Fragment 元素,因为它包含其他所有内容,并且是数组中每个元素的最顶层节点。您可以删除子元素中的键。

      &lt;&gt;&lt;/&gt; 语法不支持键/属性,因此您应该以这种方式使用片段元素:

      const courseCards = courseData.map((course, index) => (
          <React.Fragment key={//some unique value}>
            <Grid item xs={12} sm={4}>
            ...
          </React.Fragment>
      

      【讨论】:

        【解决方案3】:

        map 中提供的密钥应该是唯一的,这样做

        <Grid key={i} item xs={12} sm={4}>
          ...
        </Grid>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-09-21
          • 2021-02-16
          • 2017-02-03
          • 1970-01-01
          • 2022-01-10
          相关资源
          最近更新 更多