首页 > 解决方案 > BeforeUpload 不会在 promise 已解决时触发上传

问题描述

使用React, 和antd

我的组件中有以下代码:

<Upload
action={HttpService.getBaseUrl(`post_import_csv`, HttpService.AuditcoreAPIBasePath)}
headers={{"Authorization": `Bearer ${AuthHelper.getAuthKey()}`}}
showUploadList={false}
multiple={false}
beforeUpload={(file: RcFile): PromiseLike<any> => {
    this.setCSV(file);
    return new Promise((resolve) => {
        this.state.requestUpload.pipe(take(1)).subscribe(() => {
            resolve(file);
            console.log('resolved')
        });
    })
}}></Upload>

基本上我希望我beforeUpload在上传文件之前等待用户单击按钮。我这样做是通过返回一个 Promise 并等待一个在按钮单击时触发的 rxjs Suject 来解决这个 Promise。几乎遵循文档

这是按钮代码:

<Button
    onClick={(e): void => {
        this.state.requestUpload.next(true);
    }}
    >
    Upload
</Button>

它工作得很好,但文件从未上传,我确实看到了我的日志resolved,但我的控制台中没有网络调用的痕迹。

标签: promiserxjsantd

解决方案


我使用这种更清洁的方法进行了修复:

https://codesandbox.io/s/xvkj90rwkz

基本上,有一个处理上传的自定义函数。它没有解释为什么我的棘手解决方案不起作用,但我让它起作用了。


import React from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import './index.css';
import { Upload, Button, Icon, message } from 'antd';
import reqwest from 'reqwest';

class Demo extends React.Component {
  state = {
    fileList: [],
    uploading: false,
  };

  handleUpload = () => {
    const { fileList } = this.state;
    const formData = new FormData();
    fileList.forEach(file => {
      formData.append('files[]', file);
    });

    this.setState({
      uploading: true,
    });

    // You can use any AJAX library you like
    reqwest({
      url: 'https://www.mocky.io/v2/5cc8019d300000980a055e76',
      method: 'post',
      processData: false,
      data: formData,
      success: () => {
        this.setState({
          fileList: [],
          uploading: false,
        });
        message.success('upload successfully.');
      },
      error: () => {
        this.setState({
          uploading: false,
        });
        message.error('upload failed.');
      },
    });
  };

  render() {
    const { uploading, fileList } = this.state;
    const props = {
      onRemove: file => {
        this.setState(state => {
          const index = state.fileList.indexOf(file);
          const newFileList = state.fileList.slice();
          newFileList.splice(index, 1);
          return {
            fileList: newFileList,
          };
        });
      },
      beforeUpload: file => {
        this.setState(state => ({
          fileList: [...state.fileList, file],
        }));
        return false;
      },
      fileList,
    };

    return (
      <div>
        <Upload {...props}>
          <Button>
            <Icon type="upload" /> Select File
          </Button>
        </Upload>
        <Button
          type="primary"
          onClick={this.handleUpload}
          disabled={fileList.length === 0}
          loading={uploading}
          style={{ marginTop: 16 }}
        >
          {uploading ? 'Uploading' : 'Start Upload'}
        </Button>
      </div>
    );
  }
}

ReactDOM.render(<Demo />, document.getElementById('container'));


推荐阅读