I'm trying to display a list of files which I will upload . I used react-dropzone library to drag and drop files. the dropped files are not stored in files array using the useState hook
import React, { useState, Fragment } from "react";
import { useDropzone } from "react-dropzone";
import "./App.css";
export default function App() {
const [files, setFiles] = useState([]);
const onDrop = acceptedFiles => {
setFiles(
acceptedFiles.map(file => {
return files.concat(file);
})
);
};
const { getRootProps, getInputProps } = useDropzone({ onDrop });
return (
<Fragment>
<div {...getRootProps()} className="input-area">
{
<div>
<p className="input-text">Drop the files here ...</p>
</div>
}
<input {...getInputProps()} />
</div>
<div>
Files :
{
files.map(file => <div>{file.path} </div>)
}
</div>
</Fragment>
);
}
Here is the codesandbox link for the same https://codesandbox.io/s/hungry-margulis-ehgg2?file=/src/App.js:0-801
That's because you are using the useState Hook wrong. If you want to concat something to a state, you should use the functional parameter of setFiles. You can do it like this:
const onDrop = acceptedFiles => {
setFiles(files => files.concat(...acceptedFiles));
};
Otherwise you could do the following:
const onDrop = useCallback(acceptedFiles => {
setFiles(files.concat(...acceptedFiles));
}, [files]);
The useCallback Hook takes the files state as dependency and if that array changes, the method gets invalided from the cache :) But I would prefere the first example, because of the function you always have to correct state!
Take a look here: