我正在开发一个使用 React 和 Firestore 的项目。 我正在开发一个页面,该页面将读取多个图像,并且这些图像的某些字段将被更改。一旦进行更改,我只希望更新一个图像文档,而不是页面上的所有内容,因此 onSnapshot。 每当进行更改时,onSnapshot 侦听器都会不断添加到我拥有的图像中。我知道每次调用 useEffect 时都会添加相同的图像,但我不知道如何修复它。我已经看到了一些解决方案here,但它们不适合 ID 数组,我在更改它时需要引用文档。
export default function Images({ user }) {
const [images, setImages] = useState([]);
const [ids, setIDs] = useState([]);
useEffect(() => {
const colRef = collection(db, "images");
const q = query(colRef, where("user", "==", user));
onSnapshot(q, (snapshot) => {
snapshot.docs.forEach((doc) => {
setImages((prev) => [...prev, doc.data()]);
setIDs((prev) => [...prev, doc.id]);
});
});
}, [user]);
return (
<>
{images && (
<div className="m-4 grid grid-cols-2 grid-flow-row">
{images.map((image, index) => {
const imageID = ids[index];
return <Labels image={image} imageID={imageID} />;
})}
</div>
)}
</>
);
}
任何见解将不胜感激。
这里的问题是您正在使用
[...prev, doc.data()]
不是吗?这将导致阵列在每次快照更改时不断累加。
您可以做的是通过 snapshot.docs
进行映射,然后获取结果并将其设置为您的状态:
useEffect(() => {
const colRef = collection(db, "images");
const q = query(colRef, where("user", "==", user));
onSnapshot(q, (snapshot) => {
const docs = snapshot.docs;
setIDs(docs.map(doc => doc.id);
setImages(docs.map(doc => doc.data());
});
}, [user]);