循环遍历多个图像的数组以单独上传到AWS s3 ReactJS

Jor*_*man 2 arrays amazon-s3 amazon-web-services reactjs aws-amplify

我正在构建一个上传页面,该页面应该拍摄多个图像并使用 AWS amplify 存储将它们上传到 aws s3。

\n\n

我有一些问题

\n\n
    \n
  • 我需要在上传之前将所有图像编码为 base64 格式。

  • \n
  • 它一次只允许上传一张图像,因此我需要循环遍历文件数组并单独上传每个图像。

  • \n
  • 我无法使用file.name.

  • \n
\n\n

我应该如何循环遍历图像数组,files将它们编码为 base64,并单独上传每个图像?

\n\n

下面的代码适用于一次上传一张图像,但文件名未定义。

\n\n
 const file = useRef(null);\n\n function handleFileChange(event) {\n\n        file.current = btoa(event.target.files); \n\n   console.log(event.target.files) ///// length: 7\n                           /// 0: File {name: "921 crest road (19 of 91).jpg", lastModified: 1579836842179, lastModifiedDate: Thu Jan 23 2020 22:34:02 GMT-0500 (Eastern Standard Time), webkitRelativePath: "", size: 13998488, \xe2\x80\xa6}\n                          /// 1: File {name: "921 crest road (20 of 91).jpg", lastModified: 1579836859659, lastModifiedDate: Thu Jan 23 2020 22:34:19 GMT-0500 (Eastern Standard Time), webkitRelativePath: "", size: 14433420, \xe2\x80\xa6}\n                         /// 2: File {name: "921 crest road (21 of 91).jpg", lastModified: 1579836860868, lastModifiedDate: Thu Jan 23 2020 22:34:20 GMT-0500 (Eastern Standard Time), webkitRelativePath: "", size: 14524865, \xe2\x80\xa6}\n                        /// 3: File {name: "921 crest road (22 of 91).jpg", lastModified: 1579836861497, lastModifiedDate: Thu Jan 23 2020 22:34:21 GMT-0500 (Eastern Standard Time), webkitRelativePath: "", size: 13995939, \xe2\x80\xa6}\n                       /// 4: File {name: "921 crest road (23 of 91).jpg", lastModified: 1579836884687, lastModifiedDate: Thu Jan 23 2020 22:34:44 GMT-0500 (Eastern Standard Time), webkitRelativePath: "", size: 13982365, \xe2\x80\xa6}\n                      /// 5: File {name: "921 crest road (24 of 91).jpg", lastModified: 1579836885360, lastModifiedDate: Thu Jan 23 2020 22:34:45 GMT-0500 (Eastern Standard Time), webkitRelativePath: "", size: 14288288, \xe2\x80\xa6}\n                     /// 6: File {name: "921 crest road (25 of 91).jpg", lastModified: 1579836886846, lastMod\n\n            console.log(file.current) //// undefined\n  }\n\n\n    async function handleSubmit(event) {\n        event.preventDefault();\n        setShowLoading(true);\n\n    try {\n\n            console.log(file.name) ///undefined\n\n            const filename = `${job.jobId}---${file.name}`;\n\n            const stored = await Storage.put(filename, file.current, {\n                contentType: file.type\n        });\n\n         } catch (e) {\n            alert(e);\n            console.log(e.message)\n            }\n         setShowLoading(false);\n    }\n\n\n\n  var centerText = {textAlign: "center"}\n\n  return(\n      <IonPage>\n      <IonHeader>\n        <IonToolbar>\n      <IonButtons slot="start">\n          <IonBackButton/>\n        </IonButtons>\n          <IonTitle>Upload Images</IonTitle>\n        </IonToolbar>\n      </IonHeader>  \n      <IonContent className="ion-padding">\n\n      <form onSubmit={handleSubmit}>\n\n      <input multiple="true" type="file" onChange={(e) => handleFileChange(e)}></input>\n      <IonButton  expand="block" color="primary" strong="true" size="default" type="submit" >Upload</IonButton>\n\n      </form>\n\n    </IonContent>\n    </IonPage>\n    );\n\n\n  }\n\n\nexport default withRouter(JobInfo);\n
Run Code Online (Sandbox Code Playgroud)\n\n

更新了代码——仍然不起作用!

\n\n
const file = useRef(null);\n\n  function extractInfo(file) {\n        console.log(file)\n     return { \n      name: file.name,\n      type: file.type,\n      content: btoa(file.content),\n   };\n\n}\n\n    async function handleFileChange(event) {\n    file.current = event.target.files;\n\n  }\n\n    async function handleSubmit(event) {\n   const result = await Promise.all(\n      file.current.files\n          .map(extractInfo)\n          .map(uploadFile)\n   );\n        console.log(file.files)\n    }\n\n\n    async function uploadFile(file) {\n\n         setShowLoading(true);\n\n        try {\n\n  const filename = `${job.jobId}-${file.name}`;\n\n  const stored = await Storage.put(filename, file.current, {\n    contentType: file.type\n  });\n\n\n  } catch (e) {\n    alert(e);\n    console.log(e.message)\n\n  }\n setShowLoading(false);\n}\n  var centerText = {textAlign: "center"}\n\n  return(\n      <IonPage>\n      <IonHeader>\n        <IonToolbar>\n      <IonButtons slot="start">\n          <IonBackButton/>\n        </IonButtons>\n          <IonTitle>Upload Images</IonTitle>\n        </IonToolbar>\n      </IonHeader>  \n      <IonContent className="ion-padding">\n\n      <form onSubmit={handleSubmit}>\n\n       <input multiple type="file" ref={file} onChange={(e) => handleFileChange(e)}></input></input>\n      <IonButton  expand="block" color="primary" strong="true" size="default" type="submit" >Upload</IonButton>\n\n      </form>\n\n    </IonContent>\n    </IonPage>\n    );\n\n\n  }\n\n\nexport default withRouter(JobInfo);\n
Run Code Online (Sandbox Code Playgroud)\n

Dan*_*ran 5

您忘记在输入元素中使用 ref 。使用 Promise.all 链接所有的 Promise。

所以你的问题可以通过这样的方式解决:

const { useState, useRef } = React;

function Uploader() {
   const file = useRef({});
   
   function readContent(file) {
      return new Promise((accept, reject) => {
         const reader = new FileReader();
         reader.readAsDataURL(file);
         reader.onload = () => accept({
            name: file.name,
            type: file.type,
            content: reader.result
         });
         reader.onerror = () => reject();
      });
   }
  
   function upload(file) { // fake upload
   
      return new Promise(accept => {
         setTimeout(() => accept(file), 1000);
      });
   }
   
   function onSubmit(event) {
      event.preventDefault();
      
      const filesAsArray = [...file.current.files];
      const fileInfo = Promise.all(filesAsArray.map(readContent))
          .then(files => Promise.all(files.map(upload)))
          .then(console.log);
      
      return false;
   }
   
   return (
     <div>
       <form onSubmit={onSubmit}>
         <input ref={file} type="file" multiple={true} />
         <input type="submit" value="Upload" />
       </form>
     </div>
   );
}

ReactDOM.render(<Uploader />, document.getElementById("root"));
Run Code Online (Sandbox Code Playgroud)
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>
Run Code Online (Sandbox Code Playgroud)