File Drag and Drop Area

ReactReactBeginner
Practice Now

This tutorial is from open-source community. Access the source code

Introduction

In this lab, we will learn how to create a file drag and drop component in React using the useState and useEffect hooks. This component allows users to easily drag and drop files onto a designated area and triggers a callback function with the dropped file as an argument. By the end of this lab, you will have a better understanding of how to handle drag and drop functionality in React.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL react(("`React`")) -.-> react/FundamentalsGroup(["`Fundamentals`"]) react(("`React`")) -.-> react/AdvancedConceptsGroup(["`Advanced Concepts`"]) react(("`React`")) -.-> react/StateManagementGroup(["`State Management`"]) react/FundamentalsGroup -.-> react/jsx("`JSX`") react/FundamentalsGroup -.-> react/conditional_render("`Conditional Rendering`") react/AdvancedConceptsGroup -.-> react/hooks("`React Hooks`") react/StateManagementGroup -.-> react/use_state_reducer("`Using useState and useReducer`") subgraph Lab Skills react/jsx -.-> lab-38349{{"`File Drag and Drop Area`"}} react/conditional_render -.-> lab-38349{{"`File Drag and Drop Area`"}} react/hooks -.-> lab-38349{{"`File Drag and Drop Area`"}} react/use_state_reducer -.-> lab-38349{{"`File Drag and Drop Area`"}} end

File Drag and Drop Area

index.html and script.js have already been provided in the VM. In general, you only need to add code to script.js and style.css.

This component allows for drag and drop functionality for a single file. To implement this component, follow these steps:

  1. Create a reference called dropRef and bind it to the component's wrapper.
  2. Use the useState() hook to create the drag and filename variables. Initialize them to false and '' respectively.
  3. The variables dragCounter and drag are used to determine if a file is being dragged, while filename is used to store the dropped file's name.
  4. Create the handleDrag, handleDragIn, handleDragOut, and handleDrop methods to handle drag and drop functionality. handleDrag prevents the browser from opening the dragged file, handleDragIn and handleDragOut handle the dragged file entering and exiting the component, and handleDrop handles the file being dropped and passes it to onDrop.
  5. Use the useEffect() hook to handle each of the drag and drop events using the previously created methods.

Here is the CSS for the component:

.filedrop {
  min-height: 120px;
  border: 3px solid #d3d3d3;
  text-align: center;
  font-size: 24px;
  padding: 32px;
  border-radius: 4px;
}

.filedrop.drag {
  border: 3px dashed #1e90ff;
}

.filedrop.ready {
  border: 3px solid #32cd32;
}

Here is the JSX for the component:

const FileDrop = ({ onDrop }) => {
  const [drag, setDrag] = React.useState(false);
  const [filename, setFilename] = React.useState("");
  const dropRef = React.useRef(null);
  let dragCounter = 0;

  const handleDrag = (e) => {
    e.preventDefault();
    e.stopPropagation();
  };

  const handleDragIn = (e) => {
    e.preventDefault();
    e.stopPropagation();
    dragCounter++;
    if (e.dataTransfer.items && e.dataTransfer.items.length > 0) setDrag(true);
  };

  const handleDragOut = (e) => {
    e.preventDefault();
    e.stopPropagation();
    dragCounter--;
    if (dragCounter === 0) setDrag(false);
  };

  const handleDrop = (e) => {
    e.preventDefault();
    e.stopPropagation();
    setDrag(false);
    if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
      onDrop(e.dataTransfer.files[0]);
      setFilename(e.dataTransfer.files[0].name);
      e.dataTransfer.clearData();
      dragCounter = 0;
    }
  };

  React.useEffect(() => {
    const div = dropRef.current;
    div.addEventListener("dragenter", handleDragIn);
    div.addEventListener("dragleave", handleDragOut);
    div.addEventListener("dragover", handleDrag);
    div.addEventListener("drop", handleDrop);
    return () => {
      div.removeEventListener("dragenter", handleDragIn);
      div.removeEventListener("dragleave", handleDragOut);
      div.removeEventListener("dragover", handleDrag);
      div.removeEventListener("drop", handleDrop);
    };
  }, []);

  return (
    <div
      ref={dropRef}
      className={
        drag ? "filedrop drag" : filename ? "filedrop ready" : "filedrop"
      }
    >
      {filename && !drag ? <div>{filename}</div> : <div>Drop a file here!</div>}
    </div>
  );
};

To use the component, call ReactDOM.createRoot(document.getElementById('root')).render(<FileDrop onDrop={console.log} />);

Please click on 'Go Live' in the bottom right corner to run the web service on port 8080. Then, you can refresh the Web 8080 Tab to preview the web page.

Summary

Congratulations! You have completed the File Drag and Drop Area lab. You can practice more labs in LabEx to improve your skills.

Other React Tutorials you may like