I’ve code below. console.log from useEffect shows current "files" value, but console.log from handleInputChange function always show previous value. I understand this is because of async setState behavour, but I don’t understand how to make it work.
import React, { useState, useEffect } from 'react';
import Button from '../Button/Button';
function Card({ accept }) {
let [uploadDisabled, setUploadDisabled] = useState(true);
let [multiple, setMultiple] = useState(true);
let [files, setFiles] = useState([]);
function handleOpenClick() {
const inputEl = document.getElementById('file');
inputEl.click();
}
useEffect(() => {
console.log(files);
});
function handleInputChange(event) {
event.preventDefault();
if (!event.target.files) return;
setUploadDisabled(false);
setFiles(Array.from(event.target.files));
console.log(files)
files.forEach((file) => {
const reader = new FileReader();
reader.onload = (event) => {
const src = event.target.result;
const alt = file.name;
};
});
}
return (
<div className='card'>
<input
type='file'
id='file'
multiple={multiple}
onChange={(event) => handleInputChange(event)}
accept={accept.join(',')}
/>
<Button value='Open' className='btn' handleClick={handleOpenClick} />
<Button value='Upload' className='btn primary' disabled={uploadDisabled} />
</div>
);
}
export default Card;
2
Answers
Why you just use files from event params?
you did it shown in the above code so you expect files to be equals to event.target.files and handle it in future with forEach
So you can do
Another point is that you need array dependency in useEffect
Sorry for my bad english. I hope it solves.
You could (as @tkausl suggested) just use the
event.target.files
value directly instead of referencing the stalefiles
value, but a "more Reacty" way to do this would be to do yourFileReader
work (and the subsequent operations) in a separateuseEffect
which runs whenfiles
changes:Depending on what you end up doing in that
reader.onload
callback, you may want to take care to do cleanup when thefiles
change (e.g. the user goes in and selects extra / different files):