cris
cris

Reputation: 275

How do I make a button trigger a file input onChange in React?

I have an input of type file. For some reason it doesn't let me change the value attribute to it, and it looks ugly. I swapped it with a button, but now I need the button to somehow trigger the input file on click. How can I do this in React?

Edit:

It should trigger the input onClick, not the onChange like the title says. Unless it's the same thing in this case.

const fireInput = () => {
  let input = document.getElementById('inputFile');
}

<div>
  <input 
    id="inputFile"
    type='file'
    className='mt-2 mb-3 text-primary'
    onChange={uploadProfilePic}
  />
  <button
    type='button'
    className='btn btn-primary py-2 px-5 mb-3'
    onClick={fireInput}
  >
  Upload Picture
  </button>
</div>

Upvotes: 4

Views: 5656

Answers (4)

Goutham J.M
Goutham J.M

Reputation: 2194

You shouldn't put display:none then the element will not be in dom, you need to use opacity:0 or visibility css.

Code for doing above can be done like this:

import "./styles.css";
import { useRef } from "react";

export default function App() {
  const fileUpload = useRef(null);
  const uploadProfilePic = (e) => {
    console.log(e);
  };

  const handleUpload = () => {
    console.log(fileUpload.current.click(), "fileUpload");
  };
  return (
    <div className="App">
      <input
        type="file"
        ref={fileUpload}
        onChange={uploadProfilePic}
        style={{ opacity: "0" }}
      />
      <button onClick={() => handleUpload()}>Upload Picture</button>
    </div>
  );
}

Edit angry-banzai-6vwg3

Upvotes: 5

BTSM
BTSM

Reputation: 1663

I think you can do like this.

<div>
  <input type="file" onChange={uploadProfilePic} ref={(ref) => this.upload = ref} style={{ display: 'none' }}/>
  <button                
    type='button'
    className='btn btn-primary py-2 px-5 mb-3'
    onClick={(e) => this.upload.click()}
  >
    Upload Picture
  </button>
</div>
                                
                                

You can confirm here.

https://codesandbox.io/s/youthful-cdn-lpntx

Upvotes: 0

Shreyas Sreenivas
Shreyas Sreenivas

Reputation: 351

You could use the html label element without using any JS:


const Component = () => {
  // You should also use a ref instead of document.getElementById
  const inputRef = useRef() 

  return (
    <label>
      <div> {/*Style this however you want*/}
        Upload Photo
      </div>
      <input type="file" style={{display: "none"}} ref={inputRef} />
    </label>
   )
}

Upvotes: 1

Ajeet Shah
Ajeet Shah

Reputation: 19823

You can simply use a label:

.d-none {
  display: none;
}

.button {
  background-color: #123456;
  color: white;
  padding: 15px 32px;
  text-align: center;
}
<label for="inputFile" class="button">Upload</label>
<input type="file" id="inputFile" name="inputFile" class="d-none">

Upvotes: 2

Related Questions