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