Io sono solo di recente trattare con il AWS SDK e quindi scusate se il mio approccio è una totale assurdità.
Voglio caricare un semplice file di supporto per il mio S3. Stavo seguendo questo tutorial e finora sono in grado di caricare i file senza problemi. Per userbility una barra di avanzamento sarebbe un bel extra e quindi ero alla ricerca di come ottenere questo risultato. Ho subito scoperto che la corrente AWS SDK v3 non supporta httpUploadProgress
più , ma dobbiamo usare @aws-sdk/lib-storage
invece. Utilizzando questa libreria, io sono ancora in grado di caricare i file su S3, ma non può ottenere il progress tracker al lavoro! Presumo che questo ha qualcosa a che fare con me non comprendere appieno come affrontare async
all'interno di un Reagire componente.
Così qui è il mio minified componente esempio (sto usando Chakra UI qui)
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;
Quindi, in pratica vedo l'evento licenziamento (start upload di file). Quindi ci vuole un po ' e vedo il risultato e la Promessa Progress, 100
nella mia console. Per me questo vuol dire che la variabile di stato viene aggiornato (almeno una volta), ma il componente non ri-renderizzare?
Che cosa è che cosa sto facendo di sbagliato? Qualsiasi aiuto è apprezzato!
lib-storage
non è mai stato inteso per essere utilizzato per piccole upload di file. Purtroppo, sembra che non vi è attualmente alcuna soluzione soddisfacente quando si utilizza v3 (dato che usando il fetch api sotto il cofano) e il caricamento di file di piccole dimensioni. Quindi il tuo approccio è sicuramente una buona soluzione, ma speriamo che implementare qualcosa nel SDK molto presto.