Почему состояние перезаписывает с потерей предыдущих значений?
Я делаю загрузку drag-and-drop изображений на сервер, и перед этим отображаю их у себя. Вот как это выглядит (т.е. я перетаскиваю изображения на область(серый квадрат) и отпускаю, после чего происходят все процессы, и нижу серого квадрата отображаются перетащенные фото)
вот код чтения файлов.
function ondropHandler(e){
e.preventDefault();
if (images.length >=5) { return } // проверка кол-ва фото
let files = [...e.dataTransfer.files]
files = files.filter(file => (file.type === "image/jpeg" || file.type === "image/png") && file.size < 5242880)
files.splice(5)
setFilesSend([...filesSend, files[0]])
for(let i=0;i<files.length;i++){
var reader = new FileReader();
reader.onload = function (e) {
let img = {id:genUUID(), url:e.target.result, type:files[i].type, name: files[i].name}
setImages([...images, img] ) // вот здесь работает не так как надо
}
reader.readAsDataURL(files[i]);
}
}
Я добавляла по одному изображению и все работала хорошо (фото загружалось и отображалось). Но теперь я захотела добавить возможность перетаскивания нескольких фото. И столкнулась с проблемой, что при изменении состояния images, у меня всегда отображается одна картинка (хотя перетаскивала 3 или 5), и так получается, что в цикле при выполнении setImages([..images, img]) он сохраняет только img, а все предыдущие images не учитываются. И в итоге в состоянии хранится одна картинка, в следствии чего и отображается она одна. Почему setImages просто перезаписывает состояние? Как это исправить?
Ответы (1 шт):
попробуй присваивать через callback
setImages(prevImages => [...prevImages, img])
Update: вообще было бы здорово уменьшить количетво ререндеров до 1
function readFileAsText(file){
return new Promise(function(resolve,reject){
let fr = new FileReader();
fr.onload = function(e){
resolve({id:genUUID(), url:e.target.result, type:file.type, name: file.name});
};
fr.onerror = function(){
reject(fr);
};
fr.readAsDataURL(file);
});
}
if(!files.length) return;
// Store promises in array
for(let i = 0;i < files.length;i++){
readers.push(readFileAsText(files[i]));
}
// Trigger Promises
Promise.all(readers).then((values) => {
setImages(prevImages => [...prevImages, values])
});
