ReactJS base64 file upload
It is logged as null in the console because the state hasn't been changed at the time you print it out. When you select the file second time, the string logged in console actually belongs to the previous file you selected. The state is not yet changed to the second file you select.
Referring to React's doc:
setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value. There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains.
If you want to print the correct state, you may log it in the callback function:
self.setState({
image: upload.target.result
}, function() {
console.log(self.state.image);
});
This will also work as the state should be changed after the 1s delay:
reader.onload = function(upload) {
self.setState({
image: upload.target.result
});
};
reader.readAsDataURL(file);
setTimeout(function() {
console.log(self.state.image);
}, 1000);
Try this one
<MyTextField
id="originalFileName"
type="file"
inputProps={{ accept: 'image/*, .xlsx, .xls, .csv, .pdf, .pptx, .pptm, .ppt' }}
required
label="Document"
name="originalFileName"
onChange={e => this.handleFileRead(e)}
size="small"
variant="standard"
/>
Read File from computer
handleFileRead = async (event) => {
const file = event.target.files[0]
const base64 = await this.convertBase64(file)
console.log(base64)
}
Base64 Converter function
convertBase64 = (file) => {
return new Promise((resolve, reject) => {
const fileReader = new FileReader();
fileReader.readAsDataURL(file)
fileReader.onload = () => {
resolve(fileReader.result);
}
fileReader.onerror = (error) => {
reject(error);
}
})
}