Eu sou apenas recentemente lidar com o AWS SDK e, portanto, por favor, desculpa se a minha abordagem é um absurdo completo.
Eu quero fazer o upload de um simples arquivo de mídia para o meu S3. Eu estava seguindo este tutorial e até agora eu sou capaz de fazer upload de arquivos sem problema. Para userbility uma barra de progresso seria um bom extra e, portanto, eu estava pesquisando como fazer isso. Rapidamente descobri que o atual AWS SDK v3 não suporta httpUploadProgress
mais , mas devemos usar @aws-sdk/lib-storage
em vez disso. Usando esta biblioteca, eu ainda sou capaz de fazer upload de arquivos para o S3, mas eu não posso obter o controlador do progresso para o trabalho! Suponho que isso tenha algo a ver comigo, não entender como lidar com async
dentro de um Reagir componente.
Então aqui está a minha minified componente de exemplo (estou usando o Chakra UI aqui)
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;
Então, basicamente eu ver o evento de ser demitido (start upload de arquivo). Em seguida, ele leva um tempo e eu vejo a Promessa de resultado e o Progress, 100
no meu console. Isso significa para mim que a variável de estado é atualizado (pelo menos uma vez), mas o componente não re-renderizar?
O que é que eu estou fazendo de errado aqui? Qualquer ajuda apreciada!
lib-storage
nunca foi concebido para ser usado para pequenos carregamentos de arquivo. Infelizmente, parece que não há atualmente nenhuma solução satisfatória quando usando v3 (desde que usando a busca api sob o capô) e upload de arquivos pequenos. Assim, a sua abordagem é, definitivamente, uma boa solução, mas espero que eles vão implementar algo no SDK muito em breve.