올바르게 수행했는데도 "경고: 목록의 각 하위 요소에는 고유한 '키' 속성이 있어야 합니다."라는 메시지가 계속 나타나는 이유는 무엇입니까?
<p><br /></p><blockquote>
<p>경고: 목록의 각 하위 요소에는 고유한 '키' 속성이 있어야 합니다. </p>
<p><code>UserSidebar</code>의 렌더링 방법을 확인하세요. 자세한 내용은 https://reactjs.org/link/warning-keys를 참조하세요.</p>
</인용문>
<p>这是导致上述错误的代码:</p>
<pre class="brush:php;toolbar:false;">"react"에서 React 가져오기;
"@material-ui/core/styles"에서 { makeStyles }를 가져옵니다.
"@material-ui/core/Drawer"에서 서랍을 가져옵니다.
"@material-ui/core"에서 { 아바타, 버튼 }을 가져옵니다.
"../CryptoContext"에서 { CryptoState }를 가져옵니다.
"firebase/auth"에서 import { signOut };
"../firebase"에서 { auth, db }를 가져옵니다.
import { numberWithCommas } from "./Banner/Carousel";
"react-icons/ai"에서 { AiFillDelete }를 가져옵니다.
"firebase/firestore"에서 { doc, setDoc } 가져오기;
const useStyles = makeStyles({
컨테이너: {
폭: 350,
패딩: 25,
높이: "100%",
디스플레이: "플렉스",
flexDirection: "열",
글꼴 패밀리: "고정폭",
},
프로필: {
플렉스: 1,
디스플레이: "플렉스",
flexDirection: "열",
alignItems: "가운데",
간격: "20px",
높이: "92%",
},
로그 아웃: {
높이: "8%",
너비: "100%",
배경색상: "#EEBC1D",
여백상단: 20,
},
그림: {
폭: 200,
높이: 200,
커서: "포인터",
배경색상: "#EEBC1D",
objectFit: "포함",
},
관심 목록: {
플렉스: 1,
너비: "100%",
배경색상: "회색",
국경 반경: 10,
패딩: 15,
패딩탑: 10,
디스플레이: "플렉스",
flexDirection: "열",
alignItems: "가운데",
간격: 12,
OverflowY: "스크롤",
},
동전: {
패딩: 10,
국경 반경: 5,
검정색",
너비: "100%",
디스플레이: "플렉스",
justifyContent: "공백",
alignItems: "가운데",
배경색상: "#EEBC1D",
boxShadow: "0 0 3px 검정",
},
});
기본 함수 내보내기 UserSidebar() {
const 클래스 = useStyles();
const [state, setState] = React.useState({
오른쪽: 거짓,
});
const { 사용자, setAlert, 관심 목록, 토큰, 기호 } = CryptoState();
const 전환Drawer = (앵커, 열기) => (이벤트) => {
만약에 (
event.type === "keydown" &&
(event.key === "Tab" || event.key === "Shift")
) {
반품;
}
setState({ ...state, [앵커]: 열기 });
};
const logOut = () => {
signOut(인증);
setAlert({
공개: 사실,
유형: "성공",
메시지: "로그아웃 성공!",
});
토글 서랍();
};
const RemoveFromWatchlist = 비동기 (코인) => {
const coinRef = doc(db, "watchlist", user.uid);
노력하다 {
setDoc(
동전참조,
{ 토큰: watchlist.filter((wish) => 소원 !== coin?.id) },
{ 병합: 사실 }
);
setAlert({
공개: 사실,
메시지: `${coin.name}이(가) 관심 목록에서 제거되었습니다 !`,
유형: "성공",
});
} 잡기(오류) {
setAlert({
공개: 사실,
메시지: error.message,
유형: "오류",
});
}
};
반품 (
<div>
{["right"].map((anchor) => (
<React.Fragment key={anchor}>
<아바타
onClick={toggleDrawer(anchor, true)}
스타일={{
키: 38,
폭: 38,
여백왼쪽: 15,
커서: "포인터",
배경색상: "#EEBC1D",
}}
src={user.photoURL}
alt={user.displayName || 사용자.이메일}
/>
<서랍
앵커={앵커}
공개={상태[앵커]}
onClose={toggleDrawer(anchor, false)}
>
<div className={classes.container}>
<div className={classes.profile}>
<아바타
className={classes.picture}
src={user.photoURL}
alt={user.displayName || 사용자.이메일}
/>
<스팬
스타일={{
너비: "100%",
글꼴 크기: 25,
textAlign: "가운데",
FontWeight: "굵게",
wordWrap: "break-word",
}}
>
{user.displayName || 사용자.이메일}
</스팬>
<div className={classes.watchlist}>
<span style={{fontSize: 15, textShadow: "0 0 5px black" }}>
관심 목록
</스팬>
{tokens.map((코인) => {
if (watchlist.includes(coin.id))
반품 (
<div key={coin.id} className={classes.coin}>
<span>{coin.name}</span>
<스팬 스타일={{ 디스플레이: "플렉스", 간격: 8 }}>
{기호}{" "}
{numberWithCommas(coin.current_price.toFixed(2))}
<AiFill삭제
스타일={{ 커서: "포인터" }}글꼴 크기="16"
onClick={() =>removeFromWatchlist(코인)}
/>
</스팬>
</div>
);
그렇지 않으면 <></>를 반환합니다.
})}
</div>
</div>
<버튼
변형="포함"
className={classes.logout}
onClick={로그아웃}
>
로그 아웃
</버튼>
</div>
</서랍>
</React.Fragment>
))}
</div>
);
}</pre>
<p>필요한 경우 특정 키를 제공했지만 코드에서 오류를 찾을 수 없습니다. </p>