В моем компоненте я запускаю функцию, которая перебирает ключи в состоянии и обновляет свойства по завершении асинхронных функций.Тем не менее, похоже, что он обновляет состояние до состояния, существовавшего до запуска функции.
Это код моего компонента:
interface VideoDownloaderProps {
videos: string[];
}
const VideoDownloader: React.FC<VideoDownloaderProps> = ({ videos }) => {
const [progress, setProgress] = useState({} as { [key: string]: string });
const [isDownloading, setIsDownloading] = useState(false);
async function initialSetup(vids: string[]) {
const existingKeys = await keys();
setProgress(
vids.reduce<{ [key: string]: string }>((a, b) => {
a[b] = existingKeys.indexOf(b) > -1 ? "downloaded" : "queued";
return a;
}, {})
);
}
useEffect(() => {
initialSetup(videos);
}, [videos]);
async function download() {
setIsDownloading(true);
const existingKeys = await keys();
for (const videoUrl of videos) {
if (existingKeys.indexOf(videoUrl) === -1) {
setProgress({ ...progress, [videoUrl]: "downloading" });
const response = await fetch(videoUrl);
const videoBlob = await response.blob();
await set(videoUrl, videoBlob);
}
setProgress({ ...progress, [videoUrl]: "downloaded" });
}
setIsDownloading(false);
}
return (
<div>
<button disabled={isDownloading} onClick={download}>
Download Videos
</button>
{Object.keys(progress).map(url => (
<p key={url}>{`${url} - ${progress[url]}`}</p>
))}
</div>
);
};
По сути, это повторяетсписок URL-адресов, загружает их, а затем устанавливает URL-адрес в состоянии "downloaded"
.Однако поведение, которое я наблюдаю, заключается в том, что URL-адрес изменяется с "queued"
на "downloading"
, а затем обратно на "queued"
, как только начинается загрузка следующего URL-адреса.
Я думаю, что виновником является эта строка:
setProgress({ ...progress, [videoUrl]: "downloaded" });
Я думаю, что progress
всегда находится в том же состоянии, в котором он был при выполнении download
.
До Hooks я мог передать функцию обновления в setState
, но яя не уверен, как повторно использовать существующее состояние в useState
хуке.