Reputation: 5611
I am trying to implement an file upload button, where the data is then sent to an API. As the input field should not be visible and only the button should trigger the upload dialog, I have implemented it this way.
Problem: The File is not set to state, so I can not use a POST via axios in the
onChange
function.
import React, { useState } from 'react';
import useAxios from 'axios-hooks';
export default function BusinessCalendar(props: Props): React.ReactElement {
const hiddenFileInput = React.useRef<HTMLInputElement>(null);
const [selectedFile, setSelectedFile] = useState<any>();
const onSubmit = (): void => {
if (hiddenFileInput.current) {
hiddenFileInput.current.click();
}
};
const onChange = async (event: any): Promise<void> => {
setSelectedFile(event.target.files[0]);
await new Promise((resolve) => setTimeout(resolve, 100));
const formData = new FormData();
formData.append('File', selectedFile);
console.log('file', selectedFile, formData); // => returns `undefined`
await register({
headers: {
'Content-Type': 'multipart/form-data',
},
data: {
body: formData.get('File'), // => UNDEFINED
},
});
};
return (
<input
type="file"
ref={hiddenFileInput}
onChange={onChange}
style={{ display: 'none' }}
/>
<Button
onClick={onSubmit}
label="Add new"
icon="icon-plus"
type="secondary"
/>
</div>
);
}
Upvotes: 0
Views: 431
Reputation: 8340
React's events are synthetic and are reused after handler completes. And just as interpretator finds await
operator the current execution frame gets terminated (handler completes) and React clears event's object.
Consider using event.persist()
to override that behavior.
Upvotes: 1