Manohar
Manohar

Reputation: 1185

Display file name using react dropzone

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

Upvotes: 1

Views: 5205

Answers (2)

Jan H&#246;ck
Jan H&#246;ck

Reputation: 239

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:

Upvotes: 3

bakar_dev
bakar_dev

Reputation: 996

Check this out, i have added comment below and fixed your issue: https://codesandbox.io/s/dry-wave-457ee?file=/src/App.js

import React, { useCallback, useState, Fragment } from "react";
import { useDropzone } from "react-dropzone";
import "./App.css";

export default function App() {
  const [files, setFiles] = useState([]);

  const onDrop = acceptedFiles => {
    console.log(acceptedFiles);
    const allFiles = [...files, ...acceptedFiles]; //save all files here 
    console.log(allFiles);
    setFiles(allFiles);
  };
  const { getRootProps, getInputProps } = useDropzone({ onDrop });

  return (
    <Fragment>
      <div {...getRootProps()} className="input-area">
        {
          <div>
            <p className="input-text">Drop the files here ...</p>
            <p> drop next file here </p>
          </div>
        }
        <input {...getInputProps()} />
      </div>
      <div>
        Files :
        {files.map(file => (
          <li>{file.path}</li>
        ))}
      </div>
    </Fragment>
  );
}

Upvotes: 1

Related Questions