6

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>

4 Answers 4

7

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

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

2 Comments

It doesn't work in the sandbox. Returns an error
Please check again there was a mistake , I had not saved changes
2

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">

Comments

1

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>
   )
}

Comments

0

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

3 Comments

whats this.upload?
It's ref of input.
You can confirm at codesandbox. I added url.

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.