Home > Enterprise >  Drag Files & Select Files to React
Drag Files & Select Files to React

Time:10-23

I'm doing a application where I have to upload a list of files or I can select a button and the fileupload is open, do you recommend any library or just I do it native with the input element ?

CodePudding user response:

Based on the information you provided, it appears that your requirement will be satisfied by simple (native) input type=file and minor UI tweaks.

However, you should consider the following before deciding whether or not to install a new package for this case.

In a case, you have a list of files:

  • It may need a queue to upload the list, making it more efficient (and safer) to upload files. #UX, #reliability

  • When uploading, an animation illustrating the progress of each file is absolutely a need. #UX

 - Multiple selected files may contain undesired files that were unintentionally selected, uploading must be cancelable (eliminating the probable request for uploading the rest of the file). #UX

CodePudding user response:

For the more control in styling and customizing vanilla JS is better. Here is simple File Picker component which support both drag and pick files into list.

const DropOrChooseFile = () => {
  const [files, setFiles] = React.useState([]);

  const onDropHandler = (ev) => {
    ev.preventDefault();

    let file = "";
    if (ev.dataTransfer.items) {
      // Use DataTransferItemList interface to access the file(s)
      file =
        [...ev.dataTransfer.items]
          .find((item: any) => item.kind === "file")
          .getAsFile() ;
    } else {
      // Use DataTransfer interface to access the file(s)
      file = ev.dataTransfer.files[0];
    }
    setFiles([...files, file]);
  };

  const onDragOver = (ev) => ev.preventDefault();

  return (
    <div>
      <div> Selected files: </div>
      {files.map((file) => (
        <div key={file.name} style={{color: "green",fontWeight: "bold" }}>{file.name}</div>
      ))}
      <div style={{marginTop: 20}}></div>
      <div id="drop_zone" onDrop={onDropHandler} onDragOver={onDragOver}>
        <div>Drag and drop a file here</div>
        <div> or </div>
        <label htmlFor={"file_picker"} className="fp-label">
          Select file
        </label>
        <input
          id="file_picker"
          type="file"
          accept="image/png, image/jpeg"
          onChange={(ev) => {
            setFiles([...files, ev.target.files[0]]);
          }}
          style={{display: "none"}}
        ></input>
      </div>
    </div>
  );
};


ReactDOM.render(<DropOrChooseFile />, document.getElementById("app"));
#drop_zone {
    display: grid;
    width: 400px;
    place-content: center;
    border: 2px dashed lightgray;
    padding: 16px;
    text-align: center;
}

.fp-label {
  border: 1px solid lightgray;
  border-radius: 5px;
  padding: 8px;
}
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>

<div id="app"></div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related