Upload File Component with ReactJS

前端 未结 4 1255
面向向阳花
面向向阳花 2020-12-12 10:27

I\'ve been looking everywhere for some help on making a component to help manage uploading files from within React to an endpoint I have setup.

I\'ve tried numerous

相关标签:
4条回答
  • 2020-12-12 10:54

    There is a Dropzone npm package for this https://www.npmjs.com/package/react-dropzone

    0 讨论(0)
  • 2020-12-12 11:09

    I worked on this quite a while as well. This what I came up with.

    A Dropzone component, coupled with using superagent.

    // based on https://github.com/paramaggarwal/react-dropzone, adds image preview    
    const React = require('react');
    const _ = require('lodash');
    
    var Dropzone = React.createClass({
      getInitialState: function() {
        return {
          isDragActive: false
        }
      },
    
      propTypes: {
        onDrop: React.PropTypes.func.isRequired,
        size: React.PropTypes.number,
        style: React.PropTypes.object
      },
    
      onDragLeave: function(e) {
        this.setState({
          isDragActive: false
        });
      },
    
      onDragOver: function(e) {
        e.preventDefault();
        e.dataTransfer.dropEffect = 'copy';
    
        this.setState({
          isDragActive: true
        });
      },
    
      onDrop: function(e) {
        e.preventDefault();
    
        this.setState({
          isDragActive: false
        });
    
        var files;
        if (e.dataTransfer) {
          files = e.dataTransfer.files;
        } else if (e.target) {
          files = e.target.files;
        }
    
        _.each(files, this._createPreview);
      },
    
      onClick: function () {
        this.refs.fileInput.getDOMNode().click();
      },
    
      _createPreview: function(file){
        var self = this
          , newFile
          , reader = new FileReader();
    
        reader.onloadend = function(e){
          newFile = {file:file, imageUrl:e.target.result};
          if (self.props.onDrop) {
            self.props.onDrop(newFile);
          }
        };
    
        reader.readAsDataURL(file);
      },
    
      render: function() {
    
        var className = 'dropzone';
        if (this.state.isDragActive) {
          className += ' active';
        };
    
        var style = {
          width: this.props.size || 100,
          height: this.props.size || 100,
          borderStyle: this.state.isDragActive ? 'solid' : 'dashed'
        };
    
        return (
          <div className={className} onClick={this.onClick} onDragLeave={this.onDragLeave} onDragOver={this.onDragOver} onDrop={this.onDrop}>
            <input style={{display: 'none' }} type='file' multiple ref='fileInput' onChange={this.onDrop} />
            {this.props.children}
          </div>
        );
      }
    
    });
    
    module.exports = Dropzone
    

    Using the Dropzone.

        <Dropzone onDrop={this.onAddFile}>
          <p>Drag &amp; drop files here or click here to browse for files.</p>
        </Dropzone>
    

    When a file is added to the drop zone, add it to your list of files to upload. I add it to my flux store.

      onAddFile: function(res){
        var newFile = {
          id:uuid(),
          name:res.file.name,
          size: res.file.size,
          altText:'',
          caption: '',
          file:res.file,
          url:res.imageUrl
        };
        this.executeAction(newImageAction, newFile);
      }
    

    You can use the imageUrl to display a preview of the file.

      <img ref="img" src={this.state.imageUrl} width="120" height="120"/>
    

    To upload the files, get the list of files and send them through superagent. I'm using flux, so I get the list of images from that store.

      request = require('superagent-bluebird-promise')
      Promise = require('bluebird')
    
        upload: function(){
          var images = this.getStore(ProductsStore).getNewImages();
          var csrf = this.getStore(ApplicationStore).token;
          var url = '/images/upload';
          var requests = [];
          var promise;
          var self = this;
          _.each(images, function(img){
    
            if(!img.name || img.name.length == 0) return;
    
            promise = request
              .post(url)
              .field('name', img.name)
              .field('altText', img.altText)
              .field('caption', img.caption)
              .field('size', img.size)
              .attach('image', img.file, img.file.name)
              .set('Accept', 'application/json')
              .set('x-csrf-token', csrf)
              .on('progress', function(e) {
                console.log('Percentage done: ', e.percent);
              })
              .promise()
              .then(function(res){
                var newImg = res.body.result;
                newImg.id = img.id;
                self.executeAction(savedNewImageAction, newImg);
              })
              .catch(function(err){
                self.executeAction(savedNewImageErrorAction, err.res.body.errors);
              });
            requests.push(promise);
          });
    
          Promise
            .all(requests)
            .then(function(){
              console.log('all done');
            })
            .catch(function(){
              console.log('done with errors');
            });
        }
    
    0 讨论(0)
  • 2020-12-12 11:10

    This may help

    var FormUpload = React.createClass({
        uploadFile: function (e) {
            var fd = new FormData();    
            fd.append('file', this.refs.file.getDOMNode().files[0]);
    
            $.ajax({
                url: 'http://localhost:51218/api/Values/UploadFile',
                data: fd,
                processData: false,
                contentType: false,
                type: 'POST',
                success: function(data){
                    alert(data);
                } 
            });
            e.preventDefault()
        },
        render: function() {
            return (
                <div>                
                   <form ref="uploadForm" className="uploader" encType="multipart/form-data" >
                       <input ref="file" type="file" name="file" className="upload-file"/>
                       <input type="button" ref="button" value="Upload" onClick={this.uploadFile} />
                   </form>                
                </div>
            );
        }
    });
    

    borrowed from here How to send FormData objects with Ajax-requests in jQuery?

    0 讨论(0)
  • 2020-12-12 11:18

    I was faced with the task of getting that facebook or gmail-like behavior where your drop target highlights as soon as the user begins dragging a file anywhere over the window. There was no off-the-shelf React drag and drop solution that I could find. So, I made one.

    It is meant to be bare-bones, supplying you with a base to customize and style as your own. It provides many hooks to enable you to do this. But there is also a demo that gives you an example to go off of.

    Check it out: https://www.npmjs.com/package/react-file-drop

    Demo: http://sarink.github.io/react-file-drop/demo/

    0 讨论(0)
提交回复
热议问题