Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

187
Visualizações
Async function overwrites array state when it should update only one item

I have a file upload component. The behavior is simple: I send one upload request to the back-end per file and as the upload progress increase, I have a bar that should increase with it.

I have a state that holds every selected file and their respective progress, as such:

interface IFiles {
    file: File;
    currentProgress: number;
}
const [selectedFiles, setSelectedFiles] = useState<IFiles[]>([]);

And when the user clicks the upload button, this function will be triggered and call uploadFile for each file in my array state.

const sendFilesHandler = async () => {
        selectedFiles.map(async (file) => {
                const fileType = file.file.type.split('/')[0];
                const formData = new FormData();
                formData.append(fileType, file.file);
                formData.append('filename', file.file.name);
                await uploadFile(formData, updateFileUploadProgress);
        });
    };

Here is what the uploadFile function looks like.

const uploadFile = async (body: FormData, setPercentage: (filename: string, progress: number) => void) => {
    try {
        const options = {
            onUploadProgress: (progressEvent: ProgressEvent) => {
                const { loaded, total } = progressEvent;
                const percent = Math.floor((loaded * 100) / total);
                const fileName = body.get('filename')!.toString();

                if (percent <= 100) {
                    setPercentage(fileName, percent)
                }
            }
        };

        await axios.post(
            "https://nestjs-upload.herokuapp.com/",
            body,
            options
        );

    } catch (error) {
        console.log(error);
    }
};

As you can see, when uploadProgress is triggered it should inform call setPercentage function, which is:

const updateFileUploadProgress = (fileName: string, progress: number) => {
        console.log('Entrada', selectedFiles);
        const currentObjectIndex = selectedFiles.findIndex((x) => fileName === x.file.name);
        const newState = [...selectedFiles];
        newState[currentObjectIndex] = {
            ...newState[currentObjectIndex],
            currentProgress: progress,
        };
        setSelectedFiles(newState);
        console.log('Saída', newState);
    };

And this function should only update the object of my state array where the filenames match. However, it is overriding the whole thing. The behavior is as follows:

enter image description here

So it seems that everything is fine as long as I am updating the same object. But in the moment onUploadProgress is triggered to another object, selectedFiles states becomes its initial state again. What am I missing to make this work properly?

about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

I am not sure what is the exact reason behind this behaviour but I came up with the below unexpectedly simple solution after spending 3 hours straight on it.

const updateFileUploadProgress = (fileName: string, progress: number) => {
  setSelectedFiles(prevState => {

    const currentObjectIndex = prevState.findIndex((x) => fileName === x.file.name);
    const newState = [...prevState];

    newState[currentObjectIndex] = {
      ...newState[currentObjectIndex],
      currentProgress: progress,
    };

  return newState;
  })
};

I was able to mimic your problem locally, and solved it with the above approach. I think it was because the function (for some reason) still referenced the initial state even after rerenders.

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda