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 
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>
);
