【问题标题】:ReactJS how do i save input file multiple image base64ReactJS如何保存输入文件多个图像base64
【发布时间】:2020-08-19 10:15:49
【问题描述】:

您好,我正在尝试将多个图像文件 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。我做错了什么?

【问题讨论】:

  • 这可能是由于反应的状态更新批处理造成的。尝试对 setImages() 使用回调函数方法。即 setImages(prevImage => {/*将整个 if 条件放在回调函数的末尾,返回 imagesArray*/})。

标签: javascript reactjs filereader


【解决方案1】:

你的开发工具控制台有错误吗? 在这里工作https://stackblitz.com/edit/react-wdku9v

编辑:

这里的问题是,每次调用 uploadImage 方法时,它都会推送一个空数组。

为什么?:当使用 FileReader 时,您将一个事件附加到它等待它以“异步”加载?方式。但是你的 for 循环不要等待,所以这里是对 uploadImage 中发生的事情的描述。

输入 1 张图片:

imagesArray 被初始化为一个空数组:[]

for 循环开始:

  1. 创建一个新的 FileReader
  2. 将事件“加载”到它
  3. 用 reader.readAsDataURL(image) 读取当前图片

“加载”事件尚未调用

for 循环停止

我们用 setImages(imagesArray) 改变状态,但是此时 imagesArray 仍然是空的,导致图像永远不会显示

“load”事件被调用或稍后或之前,我们不知道。

为了防止这种情况发生,我们可以创建另一个方法,将文件阅读器封装在 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 并在 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)

【讨论】:

  • 我尝试将多个输入元素并尝试上传多个图像。并且它没有显示超过一个图像。有什么想法吗?
  • 好的,我找到了它的来源。这是更新的项目stackblitz.com/edit/react-wdku9v。问题是 readAsDataURL 是异步的,所以我将它包装在一个 Promise 中,该 Promise 在事件侦听器中解析。我应该已经看到了,抱歉错误的答案会更新它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-11
  • 1970-01-01
  • 2017-01-27
  • 2019-11-24
  • 2013-04-08
  • 2021-12-09
相关资源
最近更新 更多