Warning: Each child in a list should have a unique "key" prop.
Check the render method of
UserSidebar
. See https://reactjs.org/link/warning-keys for more information.
This is the code that causes the error shown above:
import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Drawer from "@material-ui/core/Drawer";
import { Avatar, Button } from "@material-ui/core";
import { CryptoState } from "../CryptoContext";
import { signOut } from "firebase/auth";
import { auth, db } from "../firebase";
import { numberWithCommas } from "./Banner/Carousel";
import { AiFillDelete } from "react-icons/ai";
import { doc, setDoc } from "firebase/firestore";
const useStyles = makeStyles({
container: {
width: 350,
padding: 25,
height: "100%",
display: "flex",
flexDirection: "column",
fontFamily: "monospace",
},
profile: {
flex: 1,
display: "flex",
flexDirection: "column",
alignItems: "center",
gap: "20px",
height: "92%",
},
logout: {
height: "8%",
width: "100%",
backgroundColor: "#EEBC1D",
marginTop: 20,
},
picture: {
width: 200,
height: 200,
cursor: "pointer",
backgroundColor: "#EEBC1D",
objectFit: "contain",
},
watchlist: {
flex: 1,
width: "100%",
backgroundColor: "grey",
borderRadius: 10,
padding: 15,
paddingTop: 10,
display: "flex",
flexDirection: "column",
alignItems: "center",
gap: 12,
overflowY: "scroll",
},
coin: {
padding: 10,
borderRadius: 5,
color: "black",
width: "100%",
display: "flex",
justifyContent: "space-between",
alignItems: "center",
backgroundColor: "#EEBC1D",
boxShadow: "0 0 3px black",
},
});
export default function UserSidebar() {
const classes = useStyles();
const [state, setState] = React.useState({
right: false,
});
const { user, setAlert, watchlist, tokens, symbol } = CryptoState();
const toggleDrawer = (anchor, open) => (event) => {
if (
event.type === "keydown" &&
(event.key === "Tab" || event.key === "Shift")
) {
return;
}
setState({ ...state, [anchor]: open });
};
const logOut = () => {
signOut(auth);
setAlert({
open: true,
type: "success",
message: "Logout Successfull!",
});
toggleDrawer();
};
const removeFromWatchlist = async (coin) => {
const coinRef = doc(db, "watchlist", user.uid);
try {
await setDoc(
coinRef,
{ tokens: watchlist.filter((wish) => wish !== coin?.id) },
{ merge: true }
);
setAlert({
open: true,
message: `${coin.name} Removed from the Watchlist !`,
type: "success",
});
} catch (error) {
setAlert({
open: true,
message: error.message,
type: "error",
});
}
};
return (
<div>
{["right"].map((anchor) => (
<React.Fragment key={anchor}>
<Avatar
onClick={toggleDrawer(anchor, true)}
style={{
height: 38,
width: 38,
marginLeft: 15,
cursor: "pointer",
backgroundColor: "#EEBC1D",
}}
src={user.photoURL}
alt={user.displayName || user.email}
/>
<Drawer
anchor={anchor}
open={state[anchor]}
onClose={toggleDrawer(anchor, false)}
>
<div className={classes.container}>
<div className={classes.profile}>
<Avatar
className={classes.picture}
src={user.photoURL}
alt={user.displayName || user.email}
/>
<span
style={{
width: "100%",
fontSize: 25,
textAlign: "center",
fontWeight: "bolder",
wordWrap: "break-word",
}}
>
{user.displayName || user.email}
</span>
<div className={classes.watchlist}>
<span style={{ fontSize: 15, textShadow: "0 0 5px black" }}>
Watchlist
</span>
{tokens.map((coin) => {
if (watchlist.includes(coin.id))
return (
<div key={coin.id} className={classes.coin}>
<span>{coin.name}</span>
<span style={{ display: "flex", gap: 8 }}>
{symbol}{" "}
{numberWithCommas(coin.current_price.toFixed(2))}
<AiFillDelete
style={{ cursor: "pointer" }}
fontSize="16"
onClick={() => removeFromWatchlist(coin)}
/>
</span>
</div>
);
else return <></>;
})}
</div>
</div>
<Button
variant="contained"
className={classes.logout}
onClick={logOut}
>
Log Out
</Button>
</div>
</Drawer>
</React.Fragment>
))}
</div>
);
}
I have already provided keys at specific places where it was required, yet I can’t find the mistake in the code.
2
Answers
You have to give unique key to all tags inside
map
builder.In this code :
You only give key to
<div key={coin.id} className={classes.coin}>
this tag. but not on other tags like<span>
etc.One solution is to give all tags a unique key.
Second and preferred solution is to export a functional component and give single tag to it.
for example :
and use this CoinCard and give key –
to understand, read this official docs
Let me know if you understand well
so
<></>
is returned without akey
.you can simply return an emty string to avoid the warining