Get image preview before uploading in React
Here is a simple and working solution which displays all selected images
getInitialState: function(){
return{file: []}
}
_onChange: (event)=>{
this.setState({
imgs: event.target.files
})
},
render: function(){
return(
<div>
<form>
<input
ref="file"
type="file"
name="user[image]"
multiple="true"
onChange={this._onChange}/>
</form>
{/* Display all selected images. */}
{this.state.imgs && [...this.state.imgs].map((file)=>(
<img src={URL.createObjectURL(file)} />
))}
</div>
)
}
No difference, just read your image when the load
event finishes. After the load end
event handler just set your state:
getInitialState: function(){
return{file: []}
}
_onChange: function(){
// Assuming only image
var file = this.refs.file.files[0];
var reader = new FileReader();
var url = reader.readAsDataURL(file);
reader.onloadend = function (e) {
this.setState({
imgSrc: [reader.result];
})
}.bind(this);
console.log(url) // Would see a path?
// TODO: concat files
},
render: function(){
return(
<div>
<form>
<input
ref="file"
type="file"
name="user[image]"
multiple="true"
onChange={this_onChange}/>
</form>
{/* Only show first image, for now. */}
<img src={this.state.imgSrc} />
</div>
)
}
Extending on Cels' answer, and avoiding memory leaks with createObjectURL
as @El Anonimo warns about, we could use useEffect
to create the preview and clean up after the component unmounts like so
useEffect(() => {
// create the preview
const objectUrl = URL.createObjectURL(selectedFile)
setPreview(objectUrl)
// free memory when ever this component is unmounted
return () => URL.revokeObjectURL(objectUrl)
}, [selectedFile])
The full code could look something like this
export const ImageUpload = () => {
const [selectedFile, setSelectedFile] = useState()
const [preview, setPreview] = useState()
// create a preview as a side effect, whenever selected file is changed
useEffect(() => {
if (!selectedFile) {
setPreview(undefined)
return
}
const objectUrl = URL.createObjectURL(selectedFile)
setPreview(objectUrl)
// free memory when ever this component is unmounted
return () => URL.revokeObjectURL(objectUrl)
}, [selectedFile])
const onSelectFile = e => {
if (!e.target.files || e.target.files.length === 0) {
setSelectedFile(undefined)
return
}
// I've kept this example simple by using the first image instead of multiple
setSelectedFile(e.target.files[0])
}
return (
<div>
<input type='file' onChange={onSelectFile} />
{selectedFile && <img src={preview} /> }
</div>
)
}
Please this worked perfectly for me
state = {
img: logo
}
handleChangeImage = e => {
this.setState({[e.target.name]: URL.createObjectURL(e.target.files[0])})
}
<input type="file" id="img" name="img" accept="image/*" className="w-100" onChange={this.handleChangeImage}/>
<img src={this.state.img} alt="img"/>
Check the link for more details https://medium.com/@650egor/react-30-day-challenge-day-2-image-upload-preview-2d534f8eaaa