34

I'm trying to use a react-bootstrap file input with jquery fileupload(). With straight jquery I would do $('#fileUpload').prop('files') to get the files to pass to the fileupload call. However, I don't know how to get the files correctly with react-bootstrap.

<Input type='file' label='Upload' accept='.txt' ref='fileUpload' buttonAfter={uploadFileButton}/>
5
  • @Daniel I used my answer below. What issue are you having? Commented Jul 16, 2015 at 14:12
  • See it does not work for me: jsfiddle.net/danyaljj/b1fhnb6q/2 Commented Jul 16, 2015 at 18:08
  • @Daniel You can't access this.refs outside of the react class 'Hello'. Your error "Uncaught TypeError: Cannot read property 'fileUpload' of undefined" is saying this.refs is undefined, not fileUpload. You need to put the reference in a function inside the class, e.g. jsfiddle.net/0ttmh4hs Commented Jul 16, 2015 at 18:35
  • @Daneil No worries, React's learning curve can be quite frustrating. Can you undo your downvote if that was you, that way people will know it's the correct answer. Commented Jul 16, 2015 at 19:02
  • it says "you cannot upvote unless it is edited". Could you edit something? Commented Jul 16, 2015 at 19:49

9 Answers 9

34

The more current version of this would be something like:

function MyComponent(): JSX.Element {
  const handleFileSelected = (e: React.ChangeEvent<HTMLInputElement>): void => {
    const files = Array.from(e.target.files)
    console.log("files:", files)
  }

  return (
    <input onChange={handleFileSelected} type="file" />
  )
}

The attribute is found on e.target.files which you can get from the onChange event.

EDIT: Removed unnecessary ref code, hat tip Mark in comments 🙇

Sign up to request clarification or add additional context in comments.

2 Comments

The useRef hook is not needed, the onChange handler is all that's needed
Thanks @MarkJackson I've updated the code to reflect that improvement
27

The ref string attribute is considered legacy, and will most likely be deprecated at some point in the future. The way to do this now is with a callback ref. Below I demonstrate using an ES6 arrow function.

Change your input element to:

<Input 
  type='file' label='Upload' accept='.txt' 
  buttonAfter={uploadFileButton} 
  ref={(ref) => this.fileUpload = ref}
/>

Then you can use:

const file = this.fileUpload.files[0];

And so on.

2 Comments

Have any idea on how to do this on a FormControl element, considering Input is deprecated?
This should be the accepted answer due to the new changes with React 15 :)
11

I solved file upload like this for React-Bootstrap with a custom looking button:

addFile = (event: any): void => {
    console.log(event.target.files[0]);
}

<FormGroup>
    <ControlLabel htmlFor="fileUpload" style={{ cursor: "pointer" }}><h3><Label bsStyle="success">Add file</Label></h3>
        <FormControl
            id="fileUpload"
            type="file"
            accept=".pdf"
            onChange={this.addFile}
            style={{ display: "none" }}
        />
    </ControlLabel>
</FormGroup>

Comments

10

It's pretty straight forward; I completely missed this:

var files = this.refs.fileUpload.getInputDOMNode().files;

2 Comments

Could you share where you found this answer? I'm also using React-Bootstrap to build my app, but it's kinda hard to find resources that teach how to interact with data using react-bootstrap.
@T.O I think I figured it out myself. For most of my React issues, I just pieced together knowledge of html, jquery, etc and the basic information about React and bootstrap I could find on their sites and on SO.
2

You can access the file object by binding an event handler to the onChange event of the HTML file input.

Here is a quick example using a functional component:

import React from 'react'

function UploadForm(props) {
  return(
    <div>
      <input type="file" name="docx" onChange={setFile.bind(this)} />
      <input type="button" onClick={postFile} value="Upload" />
    </div>
  )
  function postFile(event) {   
    // HTTP POST  
  }
  function setFile(event) {
    // Get the details of the files
    console.log(event.target.files)
  }
}

export default UploadForm;

Comments

1

Adding to fahad's answer, if you can't use an arrow function (due to older browser support, or for some other reason), you must bind the React context to the function.

<Input type='file' label='Upload' accept='.txt'
  buttonAfter={uploadFileButton}
  ref={ function(ref) { this.fileUpload = ref }.bind(this) }
/>

Comments

1

This worked for me.

let file = this.refs.fileUpload.files[0];

Comments

0

If you want to access the file that was uploaded using ref then you can do it as follow: fileUpload.current.files[0]

Comments

0

I am using react bootstrap and finds that files is an javaScript object not array type so we have to access it like a key value where key is the index i.e, length - 1

this code might help

const _handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const file = Object(event.currentTarget.files)[0];
console.log(file);
};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.