【问题标题】:ReactJS upload multiple image in base64 into an arrayReactJS将base64中的多个图像上传到数组中
【发布时间】:2022-07-24 00:56:38
【问题描述】:

我想创建一个基于base64image uplaoder,我想获得array 的结果,但我得到empty! 数组,我知道这可能是asynchronous 问题,但我没有不知道如何在map 中使用async, await 有什么想法吗?

const [array, setArray] = useState([]);

const fileBase64 = (img) => {
    let result = [...img];

    setUrlImage(img);

    result && result.map(function (img){
        let fileReader = new FileReader();
        fileReader.readAsDataURL(img);
        fileReader.onloadend = async () => {
            let res = await fileReader.result;
            setArray([...array, res])
        };
    })
    console.log(array)
}

const handleImage = (e) => {
    let image = [...e.target.files];
    fileBase64(image);
}

<input type="file" multiple={true} onChange={handleImage}/>

【问题讨论】:

  • 您需要将 setArray 逻辑放在 onloadend 回调中。
  • 使用console.log(array)时结果不可用,因为尚未调用回调。
  • @MaartenDev 那么解决方案是什么?你能提供答案吗?
  • setArray(array) 调用移动到. onloadend 回调中
  • @MaartenDev 仍然返回空数组,但是在选择第二个图像后它给我一个包含第一个选定图像的数组,而不是两者,任何解决方案? -- 代码更新

标签: javascript reactjs typescript ecmascript-6 babeljs


【解决方案1】:

由于这种asynchronous 的性质,在将数据urls 设置在数组中之前,正在设置状态,即push

这就是你的array返回空的原因。

要修复它,您可以使用 create Promise 在每个文件的加载事件后得到解决。并使用Promise.all,这将在每个 Promise 解决后解决,然后使用setArray

fileBase64  = (img) => {
  return new Promise((resolve, reject) => {
    let fileReader = new FileReader();
    fileReader.onerror = reject
    fileReader.onload = function () {
      resolve(fileReader.result)
    }
    fileReader.readAsDataURL(img)
  })
}

handleImage = (e) => {
  let image = e.target.files;
  Promise.all(Array.from(image).map(this.readAsDataURL))
    .then((urls) => {
      setArray(urls)
    })
    .catch((error) => {
      console.error(error)
    })
}

【讨论】:

    【解决方案2】:

    此示例在 React 中,但您可以轻松地将其修改为标准 javascript。

    如果是标准 javascript,只需将 const [images, setImages] = useState([]); 更改为 let images = []

    const [images, setImages] = useState([]);
    
    const formatImage = async() => {
      try {
        for (let i = 0; i < e.target.files.length; i++) {
          const reader = new FileReader();
          reader.readAsDataURL(e.target.files[i]);
          reader.onload = (readerEvent) => {
            images.push(readerEvent.target ? .result);
          };
        }
      } catch (error) {
        console.log(error);
      }
    };
    &lt;input type="file" multiple onChange={formatImage} /&gt;

    这是一个将这些图像放在 Firebase Firestore 上的示例,如果它是标准的 javascript,则将 setImages([]) 更改为 images = []

    const addImage = async() => {
      try {
        Promise.all(
          images.map(
            async(file: any) =>
            await addDoc(collection(db, "images"), {
              image: file,
              date: Timestamp.now(),
            })
          )
        );
    
        setImages([]);
      } catch (error) {
        console.log(error);
      }
    };

    【讨论】:

      猜你喜欢
      • 2022-07-25
      • 1970-01-01
      • 2014-06-26
      • 2017-04-26
      • 1970-01-01
      • 2016-11-12
      • 2022-01-11
      • 2021-09-28
      • 2014-07-23
      相关资源
      最近更新 更多