Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

152
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda