Я только недавно начал работать с AWS SDK, и поэтому, пожалуйста, извините, если мой подход является полной чепухой.
Я хочу загрузить простой медиафайл на свой S3. Я следовал этому руководству и до сих пор могу загружать файлы без проблем. Для удобства использования индикатор прогресса был бы хорошим дополнением, и поэтому я изучал, как этого достичь. Я быстро обнаружил, что текущий AWS SDK v3 не поддерживает httpUploadProgress
больше, но мы должны использовать@aws-sdk/lib-storage
вместо. Используя эту библиотеку, я все еще могу загружать файлы в S3, но я не могу заставить работать трекер прогресса! Я предполагаю, что это как-то связано с тем, что я не до конца понимаю, как бороться с async
в компоненте реакции.
Итак, вот мой уменьшенный пример компонента (здесь я использую пользовательский интерфейс Chakra)
const TestAWS: React.FC = () => {
const inputRef = useRef<HTMLInputElement | null>(null);
const [progr, setProgr] = useState<number>();
const region = "eu-west-1";
const bucketname = "upload-test";
const handleClick = async () => {
inputRef.current?.click();
};
const handleChange = (e: any) => {
console.log('Start file upload');
const file = e.target.files[0];
const target = {
Bucket: bucketname,
Key: `jobs/${file.name}`,
Body: file,
};
const s3 = new S3Client({
region: region,
credentials: fromCognitoIdentityPool({
client: new CognitoIdentityClient({ region: region }),
identityPoolId: "---MY ID---",
}),
});
const upload = new Upload({
client: s3,
params: target,
});
const t = upload.on("httpUploadProgress", progress => {
console.log("Progress", progress);
if (progress.loaded && progress.total) {
console.log("loaded/total", progress.loaded, progress.total);
setProgr(Math.round((progress.loaded / progress.total) * 100)); // I was expecting this line to be sufficient for updating my component
}
});
await upload.done().then(r => console.log(r));
};
console.log('Progress', progr);
return (
<InputGroup onClick={handleClick}>
<input ref={inputRef} type={"file"} multiple={false} hidden accept='video/*' onChange={e => handleChange(e)} />
<Flex layerStyle='uploadField'>
<Center w='100%'>
<VStack>
<PlusIcon />
<Text>Choose Video File</Text>
</VStack>
</Center>
</Flex>
{progr && <Progress value={progr} />}
</InputGroup>
);
};
export default TestAWS;
Таким образом, в основном я вижу, как происходит событие (запуск загрузки файла). Затем проходит некоторое время, и я вижу обещанный результат и Progress, 100
в моей консоли. Для меня это означает, что переменная состояния обновляется (по крайней мере, один раз), но компонент не перерисовывается?
В чем дело, что я здесь делаю не так? Любая помощь будет признательна!
lib-storage
никогда не предназначался для использования для небольших загрузок файлов. К сожалению, похоже, что в настоящее время нет удовлетворительного решения при использовании v3 (поскольку он использует api выборки под капотом) и загрузке небольших файлов. Таким образом, ваш подход, безусловно, является хорошим обходным путем, но, надеюсь, они очень скоро что-то внедрят в SDK.