react js handling file upload

2020-02-04 20:05发布

I'm new to react js. I want to upload image asynchronously with react js Suppose I have this code

var FormBox = React.createClass({
  getInitialState: function () {
    return {
      photo: []
    }
  },
  pressButton: function () {
    var data = new FormData();
    data.append("photo", this.state.photo);
    // is this the correct way to get file data?
  },
  getPhoto: function (e) {
    this.setState({
      photo: e.target.files[0]
    })
  },
  render: function () {
    return (
      <form action='.' enctype="multipart/form-data">
        <input type='file'  onChange={this.getPhoto}/>
        <button onClick={this.pressButton}> Get it </button>
      </form>
    )
  }
})

ReactDOM.render(<FormBox />, document.getElementById('root'))

Any answer will be appreciated!

6条回答
霸刀☆藐视天下
2楼-- · 2020-02-04 20:55

You can use whatwg-fetch to make a post request. In your pressButton() function make the following changes -

import 'whatwg-fetch';
//....

pressButton: function (url) {
    var data = new FormData();
    data.append("photo", this.state.photo);

    var options = {
      body: data,
      timeout: 3000 * 60 * 60
    };

    let callOptions = {
      method : 'POST',
      headers : {
        'Content-Type': 'application/json'
      },
      body : JSON.stringify(options.body)
    }

    return fetch(url, callOptions).then(response => response.json());
}
查看更多
女痞
3楼-- · 2020-02-04 20:57

You can make use of FileReader

var FormBox = React.createClass({
          getInitialState: function () {
            return {
              file: '',
              imagePreviewUrl: ''
            }
          },
          pressButton: function () {
            e.preventDefault();
          // TODO: do something with -> this.state.file
          console.log('handle uploading-', this.state.file);
          },
          getPhoto: function (e) {
            e.preventDefault();

            let reader = new FileReader();
            let file = e.target.files[0];

            reader.onloadend = () => {
              this.setState({
                file: file,
                imagePreviewUrl: reader.result
              });
            }

            reader.readAsDataURL(file);
            
          },
          render: function () {
            let {imagePreviewUrl} = this.state;
            let imagePreview = null;
            if (imagePreviewUrl) {
              imagePreview = (<img src={imagePreviewUrl} />);
            } else {
              imagePreview = (<div className="previewText">Please select an Image for Preview</div>);
            }
            return (
              <div>
              <form action='.' enctype="multipart/form-data">
                <input type='file'  onChange={this.getPhoto}/>
                <button onClick={this.pressButton}> Get it </button>
              </form>
              <div className="imgPreview">
                {imagePreview}
              </div>
              </div>
            )
          }
        })
        
        ReactDOM.render(<FormBox />, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react-dom.min.js"></script>
<div id="root"></div>

查看更多
smile是对你的礼貌
4楼-- · 2020-02-04 20:57
import axios from 'axios';
var FormBox = React.createClass({
  getInitialState: function () {
    return {
      photo: [],
      name : '',
      documents:[]
    }
  },
  pressButton: function () {
    var component = this
    var data = new FormData();
    data.append("photo", component.state.photo, component.state.name);
    var request = axios.post('http://localhost:3000/document', data)
        request.then(function(response){
    // you need to send data from server in response
          if(response.status == 200){
             console.log('saved in db')
             component.state.documents.push(response.data.documents)
             // pushed document data in documents array
           }
        })


  },
  getPhoto: function () {
    var uploadfile = document.getElementById(upload_doc).files[0]
    this.setState({
      photo: uploadfile, name : uploadfile.name
    })
  },
  render: function () {
    var documents = this.state.documents.map((doc)=>{
       return <div>
                <a href={doc.url}>{doc.name}</a>
                <img src={doc.photo} />
              </div>
    })
   // you can show your documents uploaded this way using map function
    return (
      <form action='.' enctype="multipart/form-data">
        <input type='file' id='upload_doc'  onChange={this.getPhoto}/>
        <button onClick={this.pressButton}> Get it </button>
        <span>{documents}</span>
        // this way you can see uploaded documents
      </form>
    )
  }
})

ReactDOM.render(<FormBox />, document.getElementById('root'))
查看更多
我只想做你的唯一
5楼-- · 2020-02-04 21:00

Use following module to select images.
https://www.npmjs.com/package/react-image-uploader

You can then upload image to server using xhr request. Following is the sample code.

var xhr  = new XMLHttpRequest();
xhr.onload = function (e) {
//your success code goes here
}
var formData = new FormData();
xhr.open("POST", url, true);
formData.append('file', fileData);
xhr.send(formData);

查看更多
forever°为你锁心
6楼-- · 2020-02-04 21:00

One more easier way, by using using axios node module axios-fileupload

npm install --save axios-fileupload

const axiosFileupload = require('axios-fileupload'); 
axiosFileupload(url,file);
查看更多
Juvenile、少年°
7楼-- · 2020-02-04 21:05

You can use React Dropzone Uploader, which gives you a dropzone that shows file previews (including image thumbnails) for dropped or chosen files, and also handles uploads for you.

import 'react-dropzone-uploader/dist/styles.css'
import Dropzone from 'react-dropzone-uploader'

const Uploader = () => {  
  return (
    <Dropzone
      getUploadParams={() => ({ url: 'https://httpbin.org/post' })} // specify upload params and url for your files
      onChangeStatus={({ meta, file }, status) => { console.log(status, meta, file) }}
      onSubmit={(files) => { console.log(files.map(f => f.meta)) }}
      accept="image/*,audio/*,video/*"
    />
  )
}

Uploads have progress indicators, and they can be cancelled or restarted. The UI is totally customizable, and the library has no dependencies.

Full disclosure: I wrote this library.

查看更多
登录 后发表回答