Home > other >  using React.Children.toArray for arrays and in console still asking for key prop
using React.Children.toArray for arrays and in console still asking for key prop

Time:09-10

In Next.js MUI Project I am using React.Children.toArray(array.map(...)) code to resolve the unique key error in the console. But It's showing the error again and again. I've looked for solution online but can't find any suitable solution here is my code,

return (
    <Section
      title={GalleryConfigData.title && GalleryConfigData.title}
      subTitle={GalleryConfigData.description && GalleryConfigData.description}
    >
      {Array.isArray(GalleryConfigData.galleries) &&
        GalleryConfigData.galleries &&
        GalleryConfigData.galleries.length > 0 && (
          <Grid container spacing={2}>
            {React.Children.toArray(
              GalleryConfigData.galleries.map((Gallery) => (
                <Grid item xs={12} sm={6} lg={3}>
                  <Paper variant="translucent">
                    <Card sx={optionStyles}>
                      {Gallery.image && (
                        <CardMedia
                          component="img"
                          alt={Gallery.title}
                          // height={Gallery.height ? Gallery.height : 420}
                          image={Gallery.image}
                          sx={{
                            border: "none",
                            width: "100%",
                            aspectRatio: "1/1",
                          }}
                        />
                      )}
                      {(Gallery.title || Gallery.description) && (
                        <CardContent sx={{ p: 0.5 }}>
                          {Gallery.title && (
                            <Typography
                              gutterBottom
                              variant="h3"
                              component="h3"
                              color="primary.main"
                            >
                              {Gallery.title}
                            </Typography>
                          )}
                          {Gallery.description && (
                            <Typography variant="body1" color="primary.light">
                              {Gallery.description}
                            </Typography>
                          )}
                        </CardContent>
                      )}
                      {Gallery.buttons.length !== 0 && (
                        <CardActions
                          sx={{
                            mt: "auto",
                            pb: 2,
                            px: 0.5,
                            justifyContent: { xs: "center", md: "flex-start" },
                            justifySelf: "flex-end",
                          }}
                        >
                          {React.Children.toArray(
                            Gallery.buttons.map((button) => (
                              <Button
                                component="a"
                                href={button.url && button.url}
                                sx={{
                                  px: 0,
                                }}
                                aria-label={`${button.text} about ${Gallery.title}`}
                                // size="small"
                              >
                                {button.text && (
                                  <>
                                    {button.text} <KeyboardArrowRightIcon />
                                  </>
                                )}
                              </Button>
                            ))
                          )}
                        </CardActions>
                      )}
                    </Card>
                  </Paper>
                </Grid>
              ))
            )}
          </Grid>
        )}
    </Section>
  );

and the error is error image

my dependency versions are leatest.

I was trying to resolve the unique key problem using React.Children.toArray(array.map(...)) but getting the unique key error in the console.

CodePudding user response:

You can add the prop key with a unique key to your nearest element of map instead of using React.Children.toArray. In your code, it should be Grid and Button.

Note that I've also added index param to map to make unique keys.

return (
  <Section
    title={GalleryConfigData.title && GalleryConfigData.title}
    subTitle={GalleryConfigData.description && GalleryConfigData.description}
  >
    {Array.isArray(GalleryConfigData.galleries) &&
      GalleryConfigData.galleries &&
      GalleryConfigData.galleries.length > 0 && (
        <Grid container spacing={2}>
          {GalleryConfigData.galleries.map((Gallery, index) => (
            <Grid item xs={12} sm={6} lg={3} key={Gallery.image   index}>
              <Paper variant="translucent">
                <Card sx={optionStyles}>
                  {Gallery.image && (
                    <CardMedia
                      component="img"
                      alt={Gallery.title}
                      // height={Gallery.height ? Gallery.height : 420}
                      image={Gallery.image}
                      sx={{
                        border: "none",
                        width: "100%",
                        aspectRatio: "1/1",
                      }}
                    />
                  )}
                  {(Gallery.title || Gallery.description) && (
                    <CardContent sx={{ p: 0.5 }}>
                      {Gallery.title && (
                        <Typography
                          gutterBottom
                          variant="h3"
                          component="h3"
                          color="primary.main"
                        >
                          {Gallery.title}
                        </Typography>
                      )}
                      {Gallery.description && (
                        <Typography variant="body1" color="primary.light">
                          {Gallery.description}
                        </Typography>
                      )}
                    </CardContent>
                  )}
                  {Gallery.buttons.length !== 0 && (
                    <CardActions
                      sx={{
                        mt: "auto",
                        pb: 2,
                        px: 0.5,
                        justifyContent: { xs: "center", md: "flex-start" },
                        justifySelf: "flex-end",
                      }}
                    >
                      {Gallery.buttons.map((button, index) => (
                        <Button
                          key={button.text   index}
                          component="a"
                          href={button.url && button.url}
                          sx={{
                            px: 0,
                          }}
                          aria-label={`${button.text} about ${Gallery.title}`}
                          // size="small"
                        >
                          {button.text && (
                            <>
                              {button.text} <KeyboardArrowRightIcon />
                            </>
                          )}
                        </Button>
                      ))}
                    </CardActions>
                  )}
                </Card>
              </Paper>
            </Grid>
          ))}
        </Grid>
      )}
  </Section>
);

CodePudding user response:

This error occurs when you are not giving each block inside the map function a prop named "key", so the following should work

return (
<Section
  title={GalleryConfigData.title && GalleryConfigData.title}
  subTitle={GalleryConfigData.description && GalleryConfigData.description}
>
  {Array.isArray(GalleryConfigData.galleries) &&
    GalleryConfigData.galleries &&
    GalleryConfigData.galleries.length > 0 && (
      <Grid container spacing={2}>
        {React.Children.toArray(
          GalleryConfigData.galleries.map((Gallery, index) => (
            <Grid item xs={12} sm={6} lg={3} key={index} >
              <Paper variant="translucent">
                <Card sx={optionStyles}>
                  {Gallery.image && (
                    <CardMedia
                      component="img"
                      alt={Gallery.title}
                      // height={Gallery.height ? Gallery.height : 420}
                      image={Gallery.image}
                      sx={{
                        border: "none",
                        width: "100%",
                        aspectRatio: "1/1",
                      }}
                    />
                  )}
                  {(Gallery.title || Gallery.description) && (
                    <CardContent sx={{ p: 0.5 }}>
                      {Gallery.title && (
                        <Typography
                          gutterBottom
                          variant="h3"
                          component="h3"
                          color="primary.main"
                        >
                          {Gallery.title}
                        </Typography>
                      )}
                      {Gallery.description && (
                        <Typography variant="body1" color="primary.light">
                          {Gallery.description}
                        </Typography>
                      )}
                    </CardContent>
                  )}
                  {Gallery.buttons.length !== 0 && (
                    <CardActions
                      sx={{
                        mt: "auto",
                        pb: 2,
                        px: 0.5,
                        justifyContent: { xs: "center", md: "flex-start" },
                        justifySelf: "flex-end",
                      }}
                    >
                      {React.Children.toArray(
                        Gallery.buttons.map((button, btnIndex) => (
                          <Button key={btnIndex}
                            component="a"
                            href={button.url && button.url}
                            sx={{
                              px: 0,
                            }}
                            aria-label={`${button.text} about ${Gallery.title}`}
                            // size="small"
                          >
                            {button.text && (
                              <>
                                {button.text} <KeyboardArrowRightIcon />
                              </>
                            )}
                          </Button>
                        ))
                      )}
                    </CardActions>
                  )}
                </Card>
              </Paper>
            </Grid>
          ))
        )}
      </Grid>
    )}
</Section>

);

  • Related