我正在尝试在我的 React 应用程序中实现多图像文件选择器。
这是我的输入元素:
<input
type="file"
multiple
onChange={handleImageChange}
/>
{renderPhotos(venueImages)}
这些是选择文件时调用的函数:
const [venueImages, setVenueImages] = useState([]);`
const renderPhotos = source => {
console.log(source); ////////log 1
return source.map(photo => {
return <img src={photo} key={photo} />;
});
};
const handleImageChange = e => {
if (e.target.files) {
const filesArray = Array.from(e.target.files);
console.log(filesArray); ///////// log 2
filesArray.forEach(file => {
const tempUrl = URL.createObjectURL(file);
console.log(tempUrl); ////// log 3
setVenueImages([...venueImages, tempUrl]);
});
}
};
我打电话给renderPhotos
,在上传之前显示所有选定照片的预览。
我面临的问题如下: 例如,如果我选择 5 张照片,则最终只会在屏幕上呈现 1 张照片。 我已经在handleImageChange
中插入了控制台日志,而我得到的记录让我更加困惑。 第二个日志(我已经在我的代码中对它们进行了编号(打印一个包含 5 个文件的数组。 从日志 3 开始,我将为每个文件获得新生成的临时 URL 的 5 个日志。
但是日志 1,只会打印一次。
现在 - 如果我单击输入元素以选择更多文件,我最终会得到另一个渲染图像。 所以基本上每次我选择图像时,无论我选择多少,我只会再渲染一张图像。
问题是您在setVenueImages
调用中引用了venueImages
数组。由于setVenueImages
执行的状态更新是异步的,因此无法确定venueImages
包含所有以前的状态更新。
可以向 set state 函数传递一个接受旧值的函数,而不仅仅是向其传递新值。这将确保您的状态更新是连续的。将您的setVenueImages
呼叫替换为以下内容:
setVenueImages(prevImages => [...prevImages, tempUrl]);
我建议的另一个更改是对所有图像进行串联,而不是逐个添加它们。这应该更快。
const handleImageChange = e => {
if (e.target.files) {
const filesArray = Array.from(e.target.files).map(file => URL.createObjectURL(file));
console.log(filesArray); ///////// log 2
setVenueImages(prevImages => prevImages.concat(filesArray));
}
};
发生这种情况是因为当您保存tempUrl
时,只有一个网址被保存。也不要使用逐个添加图像来设置状态。
handleImageChange
函数的更新版本可以是
const handleImageChange = e => {
if (e.target.files) {
const filesArray = Array.from(e.target.files);
const tempUrls = filesArray.map(file => URL.createObjectURL(file)))
setVenueImages([...venueImages, ...tempUrls])
}
};