I am new to React and trying to build an application where I want to press a custom button which will open a file dialog and upload a file on selecting it. Here is my code:
class ComposeButtons extends Component{
constructor(props) {
super(props);
this.state={
selectedFile: null
};
this.myInput = React.createRef();
}
fileSelectedHandler = (event) => {
console.log(event.target.files[0]);
this.setState({
selectedFile: event.target.files[0]
})
};
triggerClick = () => {
this.myInput.current.click()
};
fileUploadHandler = () => {
/* file upload triggered */
console.log('file upload triggered');
};
render() {
return(
<div className={"composeForm-area"}>
<div>
<Input
style={{display:'none'}}
type={"file"}
onChange={this.fileSelectedHandler}
ref={this.myInput}
/>
<Button onClick={this.triggerClick}
onChange={this.fileUploadHandler}
style={{ backgroundColor: '#DDDCDC'}}>
<Icon style={{ fontSize: '20px'}} type="camera" />
</Button>
</div>
</div>
)
}
}
export default ComposeButtons;
My current output:
I only get a clickable icon like above, however, upon clicking it throws:
Uncaught TypeError: _this.myInput.current.click is not a function
at eval (ComposeButtons.js:88)
at Button._this.handleClick (button.js:143)
at HTMLUnknownElement.callCallback (react-dom.development.js:14
What I want:
I simply want to open a file dialog to select file when i click this camera button and after i select and press ok in file dialog, it should close and trigger fileUploadHandler
function printing the message on the console. That's all!
What I tried:
Apart from code above I tried to replace code inside div in render method with this code:
<div>
<Input
id="myInput"
style={{display:'none'}}
type={"file"}
onChange={this.fileSelectedHandler}
ref={(ref) => this.myInput = ref}
/>
<Button onClick={(e) => this.myInput.click() }
style={{ backgroundColor: '#DDDCDC'}}>
<Icon style={{ fontSize: '20px'}} type="camera" />
</Button>
</div>
I also followed almost all the answers on stackoverflow but nothing seems to working for me. It will be really helpful if someone can point me in right direction.
This is my first hobby project in React.
As far as I got your question. All we can do is add a label
tag referring to the input type file
using the for
attribute in the label tag. By doing this we don't need to use ref
For info in this link.
Now all that needed to be done is to write appropriate css for the label
tag
<div>
<label htmlFor="myInput"><Icon style={{ fontSize: '20px'}} type="camera" /></label>
<input
id="myInput"
style={{display:'none'}}
type={"file"}
onChange={this.fileSelectedHandler}
/>
</div>
After that, to trigger file upload. we can call fileUploadHandler
after fileSelectedHandler
is called.
fileSelectedHandler = (event) => {
console.log(event.target.files[0]);
this.setState({
selectedFile: event.target.files[0]
}, () => this.fileUploadHandler());
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With