异步函数将元素两次添加到 React 中的数组
Async Function Adding Elements Twice to an Array in React
我有一个 React 页面,它从 firebase 的文件夹中提取图像,然后在 div 中动态显示它们。目前,当网站加载时,由于启用了 React StrictMode,我编写的用于提取图像的自定义钩子被调用了两次。图像被添加了两次,因为函数正在加载图像,而组件重新安装并且此时图像状态数组的长度仍然为 0。我知道删除 StrictMode 可以解决这个问题,但我想知道是否有更好的解决方案。
import { useEffect, useRef, useState } from "react"
import { storage } from './Firebase'
import { getDownloadURL, listAll, ref } from 'firebase/storage'
const useImages = () => {
const [loaded, setLoaded] = useState(false);
const [images, setImages] = useState([]);
useEffect(() => {
const fetchImages = () => {
const imageFolder = ref(storage, "images/");
listAll(imageFolder).then((folderItems) => {
folderItems.items.forEach((imageRef) => {
getDownloadURL(imageRef).then((imageLink) => {
setImages((prevImages) => [...prevImages, imageLink]);
});
});
});
}
if (!loaded) {
setLoaded(true);
fetchImages();
}
}, []);
return images;
}
const Gallery = () => {
const imageContainer = useRef(0);
const images = useImages();
// ON LOAD
useEffect(() => {
}, []);
return (
<div>
<div ref={imageContainer}>
{images.map((link) =>
<img width={200} src={link} />
)}
</div>
</div>
)
}
export default Gallery
您可以尝试以下方法之一来防止重复。
初步检查
...
getDownloadURL(imageRef).then((imageLink) => {
if(images.indexOf(imageLink) !== -1) return;
setImages((prevImages) => [...prevImages, imageLink]);
});
...
设置
...
getDownloadURL(imageRef).then((imageLink) => {
setImages((prevImages) => [...new Set([...prevImages, imageLink])]);
});
...
我有一个 React 页面,它从 firebase 的文件夹中提取图像,然后在 div 中动态显示它们。目前,当网站加载时,由于启用了 React StrictMode,我编写的用于提取图像的自定义钩子被调用了两次。图像被添加了两次,因为函数正在加载图像,而组件重新安装并且此时图像状态数组的长度仍然为 0。我知道删除 StrictMode 可以解决这个问题,但我想知道是否有更好的解决方案。
import { useEffect, useRef, useState } from "react"
import { storage } from './Firebase'
import { getDownloadURL, listAll, ref } from 'firebase/storage'
const useImages = () => {
const [loaded, setLoaded] = useState(false);
const [images, setImages] = useState([]);
useEffect(() => {
const fetchImages = () => {
const imageFolder = ref(storage, "images/");
listAll(imageFolder).then((folderItems) => {
folderItems.items.forEach((imageRef) => {
getDownloadURL(imageRef).then((imageLink) => {
setImages((prevImages) => [...prevImages, imageLink]);
});
});
});
}
if (!loaded) {
setLoaded(true);
fetchImages();
}
}, []);
return images;
}
const Gallery = () => {
const imageContainer = useRef(0);
const images = useImages();
// ON LOAD
useEffect(() => {
}, []);
return (
<div>
<div ref={imageContainer}>
{images.map((link) =>
<img width={200} src={link} />
)}
</div>
</div>
)
}
export default Gallery
您可以尝试以下方法之一来防止重复。
初步检查
...
getDownloadURL(imageRef).then((imageLink) => {
if(images.indexOf(imageLink) !== -1) return;
setImages((prevImages) => [...prevImages, imageLink]);
});
...
设置
...
getDownloadURL(imageRef).then((imageLink) => {
setImages((prevImages) => [...new Set([...prevImages, imageLink])]);
});
...