Ja dopiero niedawno zacząłem pracować z AWS SDK, i dlatego, proszę, przepraszam, jeśli moje podejście jest kompletna bzdurę.
Chcę pobrać prosty plik multimedialny na swój S3. Śledzę tej instrukcji i nadal mogę pobierać pliki bez problemów. Dla wygody użytkowania wskaźnik postępu byłby dobrym dodatkiem, więc uczyłem się, jak to osiągnąć. Szybko okazało się, że bieżący AWS SDK v3 nie obsługuje httpUploadProgress
więcej, ale musimy wykorzystać@aws-sdk/lib-storage
zamiast. Za pomocą tej biblioteki, nadal mogę pobierać pliki w S3, ale nie mogę zmusić do pracy tracker postępu! Zakładam, że ma to coś wspólnego z tym, że ja nie do końca rozumiem, jak walczyć z async
w składniku reakcji.
Tak więc, oto mój obniżonego przykład komponentu (tutaj używam interfejs użytkownika 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;
W ten sposób, w zasadzie widzę, jak odbywa się wydarzenie (rozpoczęcie pobierania pliku). Następnie przechodzi przez jakiś czas i widzę obiecany wynik i Progress, 100
w mojej konsoli. Dla mnie to oznacza, że zmienna stanu aktualizowana (co najmniej raz), ale składnik nie przerysowane?
O co chodzi, co ja tu robię nie tak? Każda pomoc będzie wdzięczna!
lib-storage
nigdy nie był przeznaczony do zastosowania w małych plików do pobrania. Niestety, wygląda na to, że obecnie nie ma zadowalającego rozwiązania przy użyciu v3 (ponieważ wykorzystuje api próbki pod maską) i pobierania małych plików. W ten sposób, twoje podejście jest z pewnością dobrym obejściem drogą, ale mam nadzieję, że wkrótce coś wprowadzenie w SDK.