Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React AntDesign add uploaded images to FormData

Tags:

reactjs

antd

I want to use image uploader from AntDesign library. Here is a snapshot

import { Upload, Icon, Modal } from 'antd'

class PicturesWall extends React.Component {
  state = {
    previewVisible: false,
    previewImage: '',
    fileList: [],
  }

  handleCancel = () => this.setState({ previewVisible: false })

  handlePreview = file => {
    this.setState({
      previewImage: file.url || file.thumbUrl,
      previewVisible: true,
    })
  }

  handleChange = ({ fileList }) => this.setState({ fileList })

  render() {
    const { previewVisible, previewImage, fileList } = this.state
    const uploadButton = (
      <div>
        <Icon type="plus" />
        <div className="ant-upload-text">Upload</div>
      </div>
    )
    return (
      <div className="clearfix">
        <Upload
          action="//jsonplaceholder.typicode.com/posts/"
          listType="picture-card"
          fileList={fileList}
          onPreview={this.handlePreview}
          onChange={this.handleChange}
        >
          {fileList.length >= 3 ? null : uploadButton}
        </Upload>
        <Modal
          visible={previewVisible}
          footer={null}
          onCancel={this.handleCancel}
        >
          <img alt="example" style={{ width: '100%' }} src={previewImage} />
        </Modal>
      </div>
    )
  }
}

ReactDOM.render(<PicturesWall />, mountNode)

It's so hard to understand what's going on here for me . Can I get images from this component using something like const img=event.target.files[0];?

All I want it's put that uploaded images into array and using FormData send axios.post request to the backend. I'm newbie in React .If it's something obvious pardon me.Thank you in advance

like image 735
Ginger Bread Avatar asked Feb 23 '19 20:02

Ginger Bread


1 Answers

antd's Upload component is doing the upload for you under the hood. But if you don't want to do that, and upload the file later, you can also achieve that with the help of beforeUpload prop.

From the docs:

beforeUpload: Hook function which will be executed before uploading. Uploading will be stopped with false or a rejected Promise returned. Warning:this function is not supported in IE9

I have written an example and added comments where necessary:

class PicturesWall extends React.Component {
  state = {
    previewVisible: false,
    previewImage: "",
    fileList: []
  };

  handleCancel = () => this.setState({ previewVisible: false });

  handlePreview = file => {
    this.setState({
      previewImage: file.thumbUrl,
      previewVisible: true
    });
  };

  handleUpload = ({ fileList }) => {
    //---------------^^^^^----------------
    // this is equivalent to your "const img = event.target.files[0]"
    // here, antd is giving you an array of files, just like event.target.files
    // but the structure is a bit different that the original file
    // the original file is located at the `originFileObj` key of each of this files
    // so `event.target.files[0]` is actually fileList[0].originFileObj
    console.log('fileList', fileList);

    // you store them in state, so that you can make a http req with them later
    this.setState({ fileList });
  };

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

    let formData = new FormData();
    // add one or more of your files in FormData
    // again, the original file is located at the `originFileObj` key
    formData.append("file", this.state.fileList[0].originFileObj);

    axios
      .post("http://api.foo.com/bar", formData)
      .then(res => {
        console.log("res", res);
      })
      .catch(err => {
        console.log("err", err);
      });
  };

  render() {
    const { previewVisible, previewImage, fileList } = this.state;
    const uploadButton = (
      <div>
        <Icon type="plus" />
        <div className="ant-upload-text">Upload</div>
      </div>
    );
    return (
      <div>
        <Upload
          listType="picture-card"
          fileList={fileList}
          onPreview={this.handlePreview}
          onChange={this.handleUpload}
          beforeUpload={() => false} // return false so that antd doesn't upload the picture right away
        >
          {uploadButton}
        </Upload>

        <Button onClick={this.handleSubmit} // this button click will trigger the manual upload
        >
            Submit
        </Button>

        <Modal
          visible={previewVisible}
          footer={null}
          onCancel={this.handleCancel}
        >
          <img alt="example" style={{ width: "100%" }} src={previewImage} />
        </Modal>
      </div>
    );
  }
}

ReactDOM.render(<PicturesWall />, document.getElementById("container"));
like image 174
mehamasum Avatar answered Oct 21 '22 17:10

mehamasum