score:10

I struggled it a lot and find an efficient way to handle this case.

first- you should mess with the customRequest only when you need to change to body and the request type (like using post instead of 'put' or using xml or add another extra header).

for the signing Url you can send in the action prop callback which return a promise with the right Url to upload like:

 handleUplaod = (file: any) => {
return new Promise(async (resolve, reject) => {
  const fileName = `nameThatIwant.type`;
  const url = await S3Fetcher.getPresignedUrl(fileName);
  resolve(url);
});

and render like:

render(){
    return(
    ....
    <Upload
    action={this.handleUplaod}
    ....
 Upload>

the uploader take the url from the action prop.

the onChange method which is provided also will be called any time the status of upload is changed-

onChange# The function will be called when uploading is in progress, completed or failed.

When uploading state change, it returns:

{ file: { /* ... / }, fileList: [ / ... / ], event: { / ... */ }, }

when upload started you will need to activate the file reader from that. like:

....
 fileReader = new FileReader();
 .....

onChange = (info) => {
    if (!this.fileReader.onloadend) {
      this.fileReader.onloadend = (obj) => {
        this.setState({
          image: obj.srcElement.result, //will be used for knowing load is finished.
        });
      };
    // can be any other read function ( any reading function from
    // previously created instance can be used )
    this.fileReader.readAsArrayBuffer(info.file.originFileObj);
    }
  };

notice when completed stage that event=undefind

To update the UI from the upload events you should use the options variables from customRequest and call them whenever you need.

onSuccess- should be called when you finish uploading and it will change the loading icon to the file name.

onError- will paint the file name filed to red.

onProgress- will update the progress bar and should be called with {percent: [NUMBER]} for updating.

for example in my code-

customRequest = async option => {
  const { onSuccess, onError, file, action, onProgress } = option;
  const url = action;

  await new Promise(resolve => this.waitUntilImageLoaded(resolve)); //in the next section 
  const { image } = this.state; // from onChange function above
  const type = 'image/png';
  axios
    .put(url, Image, {
      onUploadProgress: e => {
        onProgress({ percent: (e.loaded / e.total) * 100 });
      },
      headers: {
        'Content-Type': type,
      },
    })
    .then(respones => {
      /*......*/
      onSuccess(respones.body);
    })
    .catch(err => {
      /*......*/
      onError(err);
    });
};

 waitUntilImageLoaded = resolve => {
  setTimeout(() => {
    this.state.image
      ? resolve() // from onChange method
      : this.waitUntilImageLoaded(resolve);
  }, 10);
};

I used axios but you can use other libraries as well and the most important part-

render(){
return(
....
<Upload
onChange={this.onChange}
 customRequest={this.customRequest}
...>

score:11

I was struggling with that as well and then I found your question.

So the way I found to use customRequest and onChange is:

    <Upload name="file" customRequest={this.customRequest} onChange={this.onChange}>
      <Button>
        <Icon type="upload" /> Click to Upload
      </Button>
    </Upload>

  ...


  onChange = (info) => {
    const reader = new FileReader();
    reader.onloadend = (obj) => {
      this.imageDataAsURL = obj.srcElement.result;
    };
    reader.readAsDataURL(info.file.originFileObj);

    ...
  };

  ...

  customRequest = ({ onSuccess, onError, file }) => {
    const checkInfo = () => {
      setTimeout(() => {
        if (!this.imageDataAsURL) {
          checkInfo();
        } else {
          this.uploadFile(file)
            .then(() => {
              onSuccess(null, file);
            })
            .catch(() => {
              // call onError();
            });
        }
      }, 100);
    };

    checkInfo();
  };

There are probably better ways to do it, but I hope that helps you.


Related Query

More Query from same tag