ReactJS 我如何保存输入文件多个图像 base64
ReactJS how do i save input file multiple image base64
您好,我正在尝试将多个图像文件 base64 保存到数组中的状态。
const uploadImage = e => {
if (e.target.files && e.target.files.length > 0) {
// ...
let imagesArray = [];
for (let i = 0; i < e.target.files.length; i++) {
const image = e.target.files[i];
const verified = verifyImage(image);
if (verified) {
const reader = new FileReader();
const type = image.type;
reader.addEventListener('load', () => {
let imgObj = {
base64: reader.result,
name: image.name,
type,
size: image.size,
};
imagesArray.push(imgObj)
});
reader.readAsDataURL(image);
}
}
setImages(imagesArray);
}
e.target.value = null;
}
更新状态后,它不会在地图函数中呈现
{
images.length > 0
? images.map((imageObj, i) => {
return (
<div key={i}>
<img
src={imageObj.base64}
alt=''
/>
<div>
<span>{imageObj.size ? imageObj.size : '-'}</span>
<span>{imageObj.name ? imageObj.name : '-'}</span>
<span
onClick={() => removeImage(i)}
>
{translations(locale).remove}
</span>
</div>
</div>
)
})
: null
}
状态数组已更新,但 array.length 仍显示为 0。我做错了什么?
你的 devtool 控制台有错误吗?
在这里工作 https://stackblitz.com/edit/react-wdku9v
编辑:
这里的问题是每次调用 uploadImage 方法时都会推送一个空数组。
为什么?:在使用 FileReader 时,您要为其附加一个事件以等待其“异步”加载?方法。但是您的 for 循环不会等待,所以这里是对 uploadImage 中发生的事情的描述。
输入 1 张图像:
imagesArray 被初始化为一个空数组:[]
循环开始:
- 创建一个新的 FileReader
- 附加一个事件“加载”到它
- 用reader.readAsDataURL(image)
读取当前图像
“加载”事件尚未调用
for循环停止
我们使用 setImages(imagesArray) 更改状态,但是此时 imagesArray 仍然是空的,导致从不显示图像
“加载”事件是在之后还是之前调用,我们不知道。
为了防止这种情况发生,我们可以创建另一个方法,将文件 reader 封装在 Promise 中,如下所示:
const fileToDataUri = (image) => {
return new Promise((res) => {
const reader = new FileReader();
const {type, name, size} = image;
reader.addEventListener('load', () => {
res({
base64: reader.result,
name: name,
type,
size: size,
})
});
reader.readAsDataURL(image);
})
}
并且在 for 循环中,我们将连接所有承诺并在 Promise.all
中等待它们
const newImagesPromises = []
for (let i = 0; i < e.target.files.length; i++) {
newImagesPromises.push(fileToDataUri(e.target.files[i]))
}
const newImages = await Promise.all(newImagesPromises)
您好,我正在尝试将多个图像文件 base64 保存到数组中的状态。
const uploadImage = e => {
if (e.target.files && e.target.files.length > 0) {
// ...
let imagesArray = [];
for (let i = 0; i < e.target.files.length; i++) {
const image = e.target.files[i];
const verified = verifyImage(image);
if (verified) {
const reader = new FileReader();
const type = image.type;
reader.addEventListener('load', () => {
let imgObj = {
base64: reader.result,
name: image.name,
type,
size: image.size,
};
imagesArray.push(imgObj)
});
reader.readAsDataURL(image);
}
}
setImages(imagesArray);
}
e.target.value = null;
}
更新状态后,它不会在地图函数中呈现
{
images.length > 0
? images.map((imageObj, i) => {
return (
<div key={i}>
<img
src={imageObj.base64}
alt=''
/>
<div>
<span>{imageObj.size ? imageObj.size : '-'}</span>
<span>{imageObj.name ? imageObj.name : '-'}</span>
<span
onClick={() => removeImage(i)}
>
{translations(locale).remove}
</span>
</div>
</div>
)
})
: null
}
状态数组已更新,但 array.length 仍显示为 0。我做错了什么?
你的 devtool 控制台有错误吗? 在这里工作 https://stackblitz.com/edit/react-wdku9v
编辑:
这里的问题是每次调用 uploadImage 方法时都会推送一个空数组。
为什么?:在使用 FileReader 时,您要为其附加一个事件以等待其“异步”加载?方法。但是您的 for 循环不会等待,所以这里是对 uploadImage 中发生的事情的描述。
输入 1 张图像:
imagesArray 被初始化为一个空数组:[]
循环开始:
- 创建一个新的 FileReader
- 附加一个事件“加载”到它
- 用reader.readAsDataURL(image) 读取当前图像
“加载”事件尚未调用
for循环停止
我们使用 setImages(imagesArray) 更改状态,但是此时 imagesArray 仍然是空的,导致从不显示图像
“加载”事件是在之后还是之前调用,我们不知道。
为了防止这种情况发生,我们可以创建另一个方法,将文件 reader 封装在 Promise 中,如下所示:
const fileToDataUri = (image) => {
return new Promise((res) => {
const reader = new FileReader();
const {type, name, size} = image;
reader.addEventListener('load', () => {
res({
base64: reader.result,
name: name,
type,
size: size,
})
});
reader.readAsDataURL(image);
})
}
并且在 for 循环中,我们将连接所有承诺并在 Promise.all
中等待它们 const newImagesPromises = []
for (let i = 0; i < e.target.files.length; i++) {
newImagesPromises.push(fileToDataUri(e.target.files[i]))
}
const newImages = await Promise.all(newImagesPromises)