Based on your Typescript data types, it appears you want to save the actual file contents into state, not just the name of the file.
These lines in your code:
const f: File | null = event.target.files[0];
console.log(typeof(f)); // <- object
setFile(f);
...show an attempt to update state with type File
, not type string
.
Saving file contents into state can be achieved with React.useState. File contents can be converted to Base64 and stored in state as strings.
These demos on JS Fiddle use React.useState and Redux Toolkit. Source code is available on SourceHut: React.useState; Redux Toolkit.
The demos use the FileReader: readAsDataURL() method to upload files as Data URLs which can be saved as strings (not strictly as File types) in an array using React.useState.
These functions are the key to saving file content:
Read the file as a Data URL and update state
function processFiles( file ) {
var filereader = new FileReader();
filereader.onload = function onLoadCallbck( fileEvent ) {
let dataUrl = fileEvent.target.result;
let newFile = {
dataUrl,
fileName: file.name,
fileType: file.type
};
setFiles( ( prev ) => {
let list = [ ...prev ];
let newList = list.concat( newFile );
return newList;
} );
}
filereader.readAsDataURL( file );
}
Event handler for file upload field
/**
* Event listener for the file upload input field.
*/
function handleFiles( event ) {
if ( ! event.target.files.length ) {
listRef.current.innerHTML = "<p>No files selected!</p>";
} else {
listRef.current.textContent = "";
Array.prototype.forEach.call( event.target.files, processFiles );
}
}