我目前收到此重復鍵警告“警告:遇到兩個使用相同鍵的孩子”。但是,我不確定這種重復的密鑰來自哪里。我使用 fileData id 作為我的密鑰,它應該是唯一的,因為它是 firebase 生成的 id。因此,我不太確定這里發生了什么。
以下是我的代碼和我收到的警告。
MultimediaDetails.js
import React, { useEffect, useState } from "react";
import * as AiIcons from "react-icons/ai";
import * as FaIcons from "react-icons/fa";
import { database } from "../../../firebase";
import ViewImageFileModal from "../../modals/multimediaModals/view/ViewImageFileModal";
/**
* It's a component that displays audio, video, and image files
* @param props - The props object that is passed to the component.
* @returns The MultimediaDetails component is being returned.
*/
const MultimediaDetails = (props) => {
/* Destructuring the props object. */
const { pId } = props;
/* Setting the state of the component. */
const [imageData, setImageData] = useState([]);
const [imageMessage, setImageMessage] = useState(true);
const userType = JSON.parse(localStorage.getItem("admin") ?? false);
// Modal Variables
const [showViewImageModal, setShowViewImageModal] = useState(false);
const [fileData, setFileData] = useState(Object);
/**
* When the user clicks on the audio, video, or image file, the file data is set and the modal is
* toggled.
* @param obj
*/
const viewImageFile = (obj) => {
setFileData(obj);
toggleViewImageModal();
};
/* The function to toggle modal states */
const toggleAddImageModal = () => setShowAddImageModal((p) => !p);
const toggleViewImageModal = () => setShowViewImageModal((p) => !p);
useEffect(() => {
/* Query data from database and listening for changes. */
const imageQuery = database.portfolioRef.doc(pId).collection("images");
const unsubscribeImage = imageQuery.onSnapshot((snapshot) => {
if (snapshot.docs.length !== 0) {
setImageMessage(false);
setImageData(
snapshot.docs.map((doc) => ({ ...doc.data(), id: doc.id }))
);
} else {
setImageMessage(true);
}
});
return () => {
unsubscribeImage();
};
}, [pId]);
return (
<div className="multimedia-section">
<div id="image-section">
<div id="image-header">
<h6>
<u>Images</u>
</h6>
{userType ? (
<button className="addbtn" onClick={() => toggleAddImageModal()}>
<AiIcons.AiOutlinePlus /> Add Image File
</button>
) : (
<></>
)}
</div>
<div id="image-content" className="multimedia-flex">
{imageMessage ? (
<p>There is not existing images for this portfolio.</p>
) : (
<div>
{imageData.map((doc) => (
<button
key={doc.id}
className="fileBtn"
onClick={() => viewImageFile(doc)}
>
<FaIcons.FaImage /> {doc.imageName}
</button>
))}
</div>
)}
</div>
</div>
<ViewImageFileModal
show={showViewImageModal}
toggleModal={toggleViewImageModal}
pId={pId}
data={fileData}
key={fileData.id}
/>
</div>
);
};
export default MultimediaDetails;
模態的初始化值。
/* Setting the initial state of the component. */
const valueState = {
name: '',
description: ''
}
const { currentUser } = useAuth();
const [formStateDisabled, setFormStateDisabled] = useState(true);
const [deleteState, setDeleteState] = useState(false);
const [message, setMessage] = useState('');
const [imageUrl, setImageUrl] = useState("");
const [loadForm, setLoadForm] = useState(false)
const [view, setView] = useState(false);
/* Destructuring the props object. */
const { show, toggleModal } = props;
const { handleChange, handleSubmit, values, errors, loading } =
useForm(validateUpdate, valueState, handleUpdate);
useEffect(() => {
if (Object.keys(props.data).length !== 0) {
values.name = props.data.imageName;
values.description = props.data.imageDesc;
setLoadForm(true);
}
}, [])
我得到的警告(如下所示),每次我單擊模態按鈕打開按鈕時,我注意到警告實際上重復了兩次,當我關閉它時,它又重復了 2 次使其成為 4。我不確定是什么是這個原因,請幫忙!謝謝!
uj5u.com熱心網友回復:
推薦解決方案
問題是你doc.id
在重復。
imageQuery.onSnapshot
當您運行以下代碼時,您正在回呼函式中設定 imageData :
setImageData(snapshot.docs.map((doc) => ({ ...doc.data(), id: doc.id })));
您需要確保它doc.id
在此背景關系中是唯一的(因為您在按鈕的 key 屬性中使用此值)。
這是修復它的正確方法。
替代解決方案
處理它的另一種方法(作為最后的手段)是使用以下代碼,您可以在其中使用index
元素在key
屬性中的位置:
{imageData.map((doc, index) => (
<button
key={index}
className="fileBtn"
onClick={() => viewImageFile(doc)}
>
<FaIcons.FaImage /> {doc.imageName}
</button>
))}
但是根據 React 檔案不建議這樣做:
如果專案的順序可能發生變化,我們不建議對鍵使用索引。這會對性能產生負面影響,并可能導致組件狀態出現問題。查看 Robin Pokorny 的文章, 深入解釋使用索引作為鍵的負面影響。如果您選擇不為串列項分配顯式鍵,那么 React 將默認使用索引作為鍵。
如果您有興趣了解更多資訊,以下是關于為什么需要密鑰的深入解釋。
uj5u.com熱心網友回復:
而不是doc.id使用地圖項索引,如下所示。看看它是否有效。
{imageData.map((index, doc) => (
<button
key={index}
className="fileBtn"
onClick={() => viewImageFile(doc)}>
<FaIcons.FaImage /> {doc.imageName}
</button>
))}
uj5u.com熱心網友回復:
這是罪魁禍首:
{imageData.map((doc) => (
<button
key={doc.id}
className="fileBtn"
onClick={() => viewImageFile(doc)}
>
<FaIcons.FaImage /> {doc.imageName}
</button>
))}
這里的主要問題是 doc.id 是重復的,可能您的資料庫中有重復的資料,imageData
或者您的資料庫中有錯誤的資料或生成非唯一 id 的東西。
要輕松解決此問題,您可以做的是使用地圖索引。
{imageData.map((doc, index) => (
<button
key={index}
className="fileBtn"
onClick={() => viewImageFile(doc)}
>
<FaIcons.FaImage /> {doc.imageName}
</button>
))}
index
總是獨一無二的。但我建議你應該修復并看看為什么你有重復的資料,而不是僅僅用索引繞過它。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/496442.html
標籤:javascript 反应