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

148
Visualizações
React Dropzone - async function in onDrop callback doesn't update state

I'm trying to use react-dropzone onDrop with useCallback function to update the array of files dropped onto the area and trigger the upload. My code looks like this:

const [files, setFiles] = useState([]);

...

const onDrop = useCallback((acceptedFiles) => {
  setFiles(acceptedFiles);
  handleFileUpload();
}, []);

const {
  getRootProps,
  getInputProps,
  isDragActive,
} = useDropzone({ onDrop });

handleFileUpload is an asynchronous function, which uses Fetch API. When I try to log the files array inside this method, it appears to be empty, even though I updated the state before running this function.

const handleFileUpload = async () => {
  console.log(files); // <- returns empty array
}

I also tried to set different variables to indicate if the upload has started, etc. but changing the values within this method doesn't update the state of my component at all. Is it even possible to use an async function in a callback like this? Should I trigger the file upload somewhere else? I feel like I don't quite understand the concept here.

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

0

Your state will not update until after your code exits and/or relinquishes control. i.e. after you call setFiles() the files variable will still be STALE until the code returns to the event loop.

Just pass the accepted files into the function.

const onDrop = useCallback((acceptedFiles) => {
  setFiles(acceptedFiles); // <-- that won't update right away
  handleFileUpload(acceptedFiles);
}, []);

UPDATE

Here are snippets from one of my projects. I just stuff the dropped file into state, as you do. That causes the component to re-render, and when it does, I catch the updated file state in a hook, async parse the file, and return the data - which is then consumed by the component. The component shows UI states - importing if fileToImport is set and dataToImport is not yet available, etc...

// MyComponent.tsx
const MyComponent = () => {
  const [fileToImport, setFileToImport] = useState<File | undefined>()
  const [dataToImport, dataToImportError] = useReadFileData(fileToImport)

  const onDrop = useCallback(acceptedFiles => {
    setFileToImport(acceptedFiles[0])
  }, [])


//useREadFileData.ts hook
import { useEffect, useState } from 'react'

const useReadFileData = (file: File | undefined): [any[], string | undefined] => {
  const [rows, setRows] = useState<unknown[]>([])
  const [error, setError] = useState<string>()

  useEffect(() => {
    async function parseFile(file: File) {
      try {
        // snip
        setRows(rows)
      } catch (error: any) {
        if (typeof error === "object") {
          setError(error?.message ?? "Error parsing file")
        }
      }
    }
    // only if we have a file to parse
    if (file) {
      parseFile(file)
    }
  }, [file, setError, setRows])

  return [rows, error]
}

export default useReadFileData
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