Загрузка нескольких файлов в ответ - PullRequest
0 голосов
/ 12 марта 2020

Мне нужно загрузить несколько файлов (по одному (не за один раз)) на сервер с помощью API отдыха.

import React from "react";
import FlashMessage from "react-flash-message";
export class FileUpload extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      selectedFile: null,
      details: "",
      name: "",
      list_details: [],
      list_name: []
    };
    this.onChangeHandler = this.onChangeHandler.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }
  onChangeHandler = event => {
    this.setState({
      selectedFile: event.target.files,
      showMessage: false
    });
  };

  handleSubmit = event => {
    event.preventDefault();

    /* Here I wanna send one file at a time , but it sends multiple files at a time */

    const formData = new FormData();
    for (var x = 0; x < this.state.selectedFile.length; x++) {
      formData.append("inputFile", this.state.selectedFile[x]);
    }

    fetch("url", {
      method: "POST",
      body: formData
    })
      .then(res => {
        return res.json();
      })
      .then(res => {
        this.setState({
          showMessage: true
          //  details: res.data.details,
          //name: res.data.name
        });

        //console.log("Data is", res.data.name) //displays name in the console
      })
      .catch(error => console.log("ERROR message"));
  };

  render() {
    /* After storing multiple files in the server, response data contains name,details value.
Page shouldn't refresh.  Now i upload files and response data should be displayed in the page.since i don't refresh the page, I upload one more file, this time page should display this file's response data as well as previous ones. Its format should be like this[1.Name1:details1,2.Name2:details2 etc] */

    // this.setState({
    //  list_details: list.concat(details),
    // list_name: list_name.concat(name)
    //});

    return (
      <div>
        {this.state.showMessage && (
          <div>
            <FlashMessage duration={18000}>
              <strong>files have been uploaded successfully !!</strong>
            </FlashMessage>
          </div>
        )}

        <form onSubmit={this.handleSubmit}>
          <label>
            Upload a file: <br />
            <br />
            <input
              type="file"
              name="file"
              multiple
              onChange={this.onChangeHandler}
            />
          </label>
          <br />
          <br />
          <button type="submit">Upload</button>
        </form>
        <ol>
          {/* code i have tried to display response data[1.Name1:detail1,2.Name2:detail2]  */}
          {/* // {this.state.list_name.map((k) =>
               //    <li>{k} :</li>
              // )}
              // {this.state.list_details.map((k) =>
               //    <li>{k}</li>
               //)}  */}
        </ol>
      </div>
    );
  }
}

У меня есть еще одно требование: мне нужно добавить прослушиватель, чтобы программа должна ждать, пока я не получу ответ от сервера? Должен ли я использовать метод async / await ??

Пожалуйста, помогите мне .. Заранее спасибо.

1 Ответ

1 голос
/ 12 марта 2020

Вместо добавления всех файлов к одному formData и отправки его, вы можете добавить и отправить один файл для l oop, который у вас уже есть.

const formData = new FormData();
for (var x = 0; x < this.state.selectedFile.length; x++) {
  const formData = new FormData();
  formData.append('inputFile', this.state.selectedFile[x])
  fetch('url' ....
}

Код выше будет работать синхронно (selectedFile. длина файлов будет отправлена ​​одновременно). С pLimit вы можете настроить это число.

import pLimit from 'p-limit'

...

const limit = pLimit(30)
let promises = this.state.selectedFile.map( file=> {
    return limit(() => fetch logic )
})

Promise.all(promises).then( () => console.log('All files have been uploaded.') )
...