Estoy tratando de usar react-dropzone onDrop con la función useCallback para actualizar la matriz de archivos colocados en el área y activar la carga. Mi código se ve así:
const [files, setFiles] = useState([]); ... const onDrop = useCallback((acceptedFiles) => { setFiles(acceptedFiles); handleFileUpload(); }, []); const { getRootProps, getInputProps, isDragActive, } = useDropzone({ onDrop }); handleFileUpload es una función asíncrona que utiliza la API Fetch. Cuando intento registrar la matriz de files dentro de este método, parece estar vacía, aunque actualicé el estado antes de ejecutar esta función.
const handleFileUpload = async () => { console.log(files); // <- returns empty array }También traté de configurar diferentes variables para indicar si la carga comenzó, etc., pero cambiar los valores dentro de este método no actualiza el estado de mi componente en absoluto. ¿Es posible usar una función asíncrona en una devolución de llamada como esta? ¿Debo activar la carga del archivo en otro lugar? Siento que no entiendo muy bien el concepto aquí.
Su estado no se actualizará hasta que su código salga o renuncie al control. es decir, después de llamar a setFiles() , la variable de files seguirá estando OBSERVADA hasta que el código vuelva al bucle de eventos.
Simplemente pase los archivos aceptados a la función.
const onDrop = useCallback((acceptedFiles) => { setFiles(acceptedFiles); // <-- that won't update right away handleFileUpload(acceptedFiles); }, []);ACTUALIZAR
Aquí hay fragmentos de uno de mis proyectos. Simplemente relleno el archivo soltado en el estado, como lo haces tú. Eso hace que el componente se vuelva a procesar y, cuando lo hace, capturo el estado del archivo actualizado en un enlace, analizo de forma asíncrona el archivo y devuelvo los datos, que luego son consumidos por el componente. El componente muestra los estados de la interfaz de usuario: importar si fileToImport está configurado y dataToImport aún no está disponible, 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