LoginSignup
3
4

More than 5 years have passed since last update.

Ant Design の Upload で PUT を使う

Last updated at Posted at 2018-09-30

はじめに

Alibaba の Ant Design が結構イケてます。
特に Upload Component がおしゃれな挙動をしてくれるんですが、デフォルトで POST で送信しちゃうようです。
PUT で送信する要件があったのでそのナレッジを書いておきます。

PUT を使った Upload

いきなり本題です。
Class / Stateless Functional Component は省略します。
実装箇所がわかりやすいようにrender以降の部分を記載します。
(Stateless Functional Component の場合はreturn以降をご参考ください。)

import { Upload, Icon } from 'antd';

/*** 中略 ***/

  createButton = () => {
    return (
      <div>
        <Icon type={'plus'} />
        <div className="ant-upload-text">Upload</div>
      </div>
    );
  }

  render() {
    return (
      <Upload
        name={fileName}
        listType="picture-card"
        className="avatar-uploader"
        multiple={false}
        showUploadList={{ showPreviewIcon: false, showRemoveIcon: true }}
        fileList={fileList}
        action={uploadUrl}
        customRequest={(info) => {
          let xhr = new XMLHttpRequest();
          if (!uploadUrl) { return; }
          if (info.onProgress && xhr.upload) {
            xhr.upload.onprogress = function progress(e) {
              if (e.total > 0) {
                e.percent = e.loaded / e.total * 100;
              }
              info.onProgress(e);
            }
          }
          xhr.open('PUT', uploadUrl, true);
          xhr.overrideMimeType(info.file.type)
          xhr.send(info.file);
          xhr.addEventListener('loadend', (e) => {
            info.onSuccess(e, xhr);
          })
        }}
        onPreview={(file) => {
          console.log('onPreview',file);
        }}
        onRemove={(file) => {
          console.log('onRemove',file);
        }}
        beforeUpload={(file) => {
          console.log('beforeUpload',file);
        }}
        onChange={(info) => {
          console.log('onChange',info);
        }
      >
        {fileList.length >= 1 ? null : this.createButton()}
      </Upload>
    );
  }

処理の説明

createButton

アップロード前に表示するボタンアイコンのコンポーネントを作成しています。

multiple

一つのコンポーネントに対して、複数ファイルをアップロードできるかどうかの設定。
defaultでfalseなので書かなくても同じ挙動になります。

showUploadList

アップロード後のサムネイルにカーソルを当てた際、プレビューアイコンとリムーブアイコンを表示する設定です。

fileList

アップロードしたファイルの情報。
初期表示したいときは、この項目に値を設定します。

action

アップロード先の URL です。
必須項目ですが、customRequestで URL 設定した場合は使われないかもしれません。(※未確認)

customRequest

PUT を利用する際、この API を使用します。
私はXMLHttpRequest()を使いました。

xhr.upload.onprogress = function progress(e) {
  if (e.total > 0) {
    e.percent = e.loaded / e.total * 100;
  }
    info.onProgress(e);
}

この処理でプログレスバーを更新します。

xhr.addEventListener('loadend', (e) => {
  info.onSuccess(e, xhr);
})

この処理で、処理の完了をコンポーネントに連携します。

PUT の処理は比較的簡単に実装できたのですが、customRequest を利用した場合にUploadのプログレスバーの UI が動かず色々と試して上記の実装に至りました。

おわりに

もっといい実装方法や、間違いなどがありましたらご指摘いただけますと幸いです。

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4