Comment utiliser l'API HTML glisserdéposer dans React
   
L'API glisser-déposer est l'une des fonctionnalités les plus intéressantes de HTML. Il nous aide à implémenter des fonctionnalités de glisser-déposer dans les navigateurs Web.
Dans le contexte actuel, nous allons faire glisser des fichiers depuis l'extérieur du navigateur. Lors de la suppression du ou des fichiers, nous les mettons sur une liste et affichons leurs noms. Avec les fichiers en main, nous pourrions alors effectuer une autre opération sur le (s) fichier (s), par ex. téléchargez-les sur un serveur cloud.
 Dans ce didacticiel, nous allons nous concentrer sur la façon d'implémenter l'action de glisser-déposer dans une application React. Si vous avez besoin d'une implémentation JavaScript simple  vous voudrez peut-être d'abord lire « Comment créer un téléchargeur de fichiers par glisser-déposer avec JavaScript Vanilla », un excellent didacticiel écrit par Joseph Zimmerman il n'y a pas si longtemps.
 Le  dragenter  dragleave  dragover Et  drop  Événements
 Là sont huit événements de glisser-déposer différents. Chacun se déclenche à un stade différent de l'opération de glisser-déposer. Dans ce didacticiel, nous nous concentrerons sur les quatre éléments déclenchés lorsqu'un élément est déposé dans une zone de dépôt:  dragenter  dragleave  dragover  et  drop .
-  L'événement dragenterse déclenche lorsqu'un élément déplacé entre dans une cible de dépôt valide.
-  L'événement dragleavese déclenche lorsqu'un élément déplacé laisse une goutte valide
-  L'événement de survolse déclenche lorsqu'un élément déplacé est glissé sur une cible de dépôt valide. (Il se déclenche toutes les quelques centaines de millisecondes.)
-  L'événement dropse déclenche lorsqu'un élément tombe sur une cible de dépôt valide, c'est-à-dire qu'il est glissé et relâché.
 Nous pouvons transformer n'importe quel élément HTML en un élément valide supprimer la cible en définissant les attributs de gestionnaire d'événements  ondragover  et  ondrop .
Vous pouvez tout savoir sur les huit événements des documents Web MDN .
Événements glisser-déplacer dans React
Pour commencer, clonez le référentiel du didacticiel à partir de cette URL:
 https://github.com/chidimo/react-dnd.git
 Consultez la branche  01-start . Assurez-vous que le fil   est également installé. Vous pouvez l'obtenir sur  yarnpkg.com .
Mais si vous préférez, créez un nouveau projet React et remplacez le contenu de App.js par le code ci-dessous:
 importer React à partir de 'react';
import './App.css';
fonction App () {
  revenir (
    
       Composant glisser-déposer React 
    
  );
}
exporter l'application par défaut;
Remplacez également le contenu de App.css par le style CSS ci-dessous:
 .App {
  marge: 2rem;
  alignement du texte: centre;
}
h1 {
  couleur: # 07F;
}
.drag-drop-zone {
  rembourrage: 2rem;
  alignement du texte: centre;
  fond: # 07F;
  rayon-frontière: 0,5rem;
  boîte-ombre: 5px 5px 10px # C0C0C0;
}
.drag-drop-zone p {
  couleur: #FFF;
}
.drag-drop-zone.inside-drag-area {
  opacité: 0,7;
}
.dropped-files li {
  couleur: # 07F;
  rembourrage: 3px;
  alignement du texte: gauche;
  poids de police: gras;
}
Si vous avez cloné le dépôt, émettez les commandes suivantes (dans l'ordre) pour démarrer l'application:
 yarn # install dependencies
fil démarrer # démarrer l'application
 L'étape suivante consiste à créer un composant glisser-déposer. Créez un fichier  DragAndDrop.js  dans le dossier  src / . Entrez la fonction suivante dans le fichier:
 import React from 'react';
const DragAndDrop = props => {
  const handleDragEnter = e => {
    e.preventDefault ();
    e.stopPropagation ();
  };
  const handleDragLeave = e => {
    e.preventDefault ();
    e.stopPropagation ();
  };
  const handleDragOver = e => {
    e.preventDefault ();
    e.stopPropagation ();
  };
  const handleDrop = e => {
    e.preventDefault ();
    e.stopPropagation ();
  };
  revenir (
     handleDrop (e)}
      onDragOver = {e => handleDragOver (e)}
      onDragEnter = {e => handleDragEnter (e)}
      onDragLeave = {e => handleDragLeave (e)}
    >
       Faites glisser les fichiers ici pour les télécharger 
    
  );
};
exporter DragAndDrop par défaut;
 Dans le retour  div nous avons défini nos attributs de gestionnaire d'événements  HTML . Vous pouvez voir que la seule différence par rapport au HTML pur   est le boîtier en chameau.
 Le div   est maintenant une cible de dépôt valide puisque nous avons défini le  onDragOver  ] et  onDrop  attributs du gestionnaire d'événements.
Nous avons également défini des fonctions pour gérer ces événements.
 Pour chacun des gestionnaires d'événements, nous appelons  preventDefault ()  pour empêcher le navigateur d'exécuter son comportement par défaut. Le comportement par défaut du navigateur consiste à ouvrir le fichier déposé. Nous appelons également  stopPropagation ()  pour nous assurer que l'événement n'est pas propagé des éléments enfant aux parents.
 Importez le composant  DragAndDrop  dans le composant  App  App et le rendre sous l'en-tête.
 
   Composant React par glisser-déposer 
  Maintenant, visualisez le composant dans le navigateur et vous devriez voir quelque chose comme l'image ci-dessous.

 div  à convertir en zone de dépôt ( Grand aperçu ) [19659039] Si vous suivez le repo, la branche correspondante est  02-start-dragndrop  Gestion de l'état avec le  useReducer  Hook
Notre prochaine étape sera d'écrire la logique pour chacun de nos gestionnaires d'événements. Avant de faire cela, nous devons réfléchir à la façon dont nous avons l'intention de suivre les fichiers perdus. C'est ici que nous commençons à penser à la gestion des états.
Nous allons suivre les états suivants pendant l'opération de glisser-déposer:
-  dropDepth
 Ce sera un entier. Nous l'utiliserons pour garder une trace du nombre de niveaux de profondeur dans la zone de largage. Plus tard, je vais l'expliquer avec une illustration. ( Crédits à Egor Egorov pour avoir mis en lumière celui-ci pour moi! )
-  inDropZone
 Ce sera un booléen. Nous l'utiliserons pour savoir si nous nous trouvons dans la zone de dépôt ou non.
-  FileList
 Ce sera une liste. Nous allons l'utiliser pour garder une trace des fichiers qui ont été déposés dans la zone de dépôt.
 Pour gérer les états, React fournit les crochets  useState  et  useReducer . Nous allons opter pour le crochet  useReducer  étant donné que nous traiterons des situations où un état dépend de l'état précédent.
 Le crochet  useReducer  accepte un réducteur de type  (état, action) => newState  et renvoie l'état actuel associé à une méthode  dispatch .
  Vous pouvez en savoir plus sur   useReducer   dans le  React   docs . 
 À l'intérieur du composant  App  (avant la déclaration de retour  ), ajoutez le code suivant:
. ..
const reducer = (état, action) => {
  commutateur (action.type) {
    cas 'SET_DROP_DEPTH':
      return {... state, dropDepth: action.dropDepth}
    cas 'SET_IN_DROP_ZONE':
      return {... state, inDropZone: action.inDropZone};
    cas 'ADD_FILE_TO_LIST':
      return {... state, fileList: state.fileList.concat (action.files)};
    défaut:
      état de retour;
  }
};
const [data, dispatch] = React.useReducer (
  réducteur, {dropDepth: 0, inDropZone: false, fileList: []}
)
...
 Le crochet  useReducer  accepte deux arguments: un réducteur et un état initial. Il renvoie l'état actuel et une fonction  de répartition  avec laquelle mettre à jour l'état. L'état est mis à jour en envoyant une action qui contient un type   et une charge utile facultative. La mise à jour apportée à l'état du composant dépend de ce qui est renvoyé par l'instruction case à la suite du type d'action. (Notez ici que notre état initial est un objet  .)
 Pour chacune des variables d'état, nous avons défini une déclaration de cas correspondante pour le mettre à jour. La mise à jour est effectuée en invoquant la fonction  dispatch  renvoyée par  useReducer .
 Maintenant, passez  data  et  dispatch  en tant qu'accessoires   au composant  DragAndDrop  que vous avez dans votre fichier  App.js :
  En haut du composant  DragAndDrop nous pouvons accéder aux deux valeurs à partir des accessoires  .
 const {data, dispatch} = props;
 Si vous suivez le repo, la branche correspondante est  03-define-reducers .
Terminons la logique de nos gestionnaires d'événements. Notez que les points de suspension représentent les deux lignes:
 e.preventDefault ()
e.stopPropagation ()
const handleDragEnter = e => {
  ...
  dispatch ({type: 'SET_DROP_DEPTH', dropDepth: data.dropDepth + 1});
};
const handleDragLeave = e => {
  ...
  dispatch ({type: 'SET_DROP_DEPTH', dropDepth: data.dropDepth - 1});
  si (data.dropDepth> 0) retourne
  dispatch ({type: 'SET_IN_DROP_ZONE', inDropZone: false})
};
Dans l'illustration qui suit, nous avons imbriqué les zones de largage A et B. A est notre zone d'intérêt. C'est ici que nous voulons écouter les événements de glisser-déposer.

 ondragenter  et  ondragleave  (  Grand aperçu ) Lorsque vous glissez dans une zone de largage, chaque fois que nous atteignons une limite, l'événement  ondragenter  est déclenché. Cela se produit aux limites  A-in  et  B-in . Puisque nous entrons dans la zone, nous incrémentons  dropDepth .
 De même, lorsque vous sortez d'une zone de largage, chaque fois que vous atteignez une limite, l'événement  ondragleave  est déclenché. Cela se produit aux limites  A-out  et  B-out . Puisque nous quittons la zone, nous décrémentons la valeur de  dropDepth . Notez que nous ne définissons pas  inDropZone  sur  false  à la limite  B-out . C'est pourquoi nous avons cette ligne pour vérifier la dropDepth et le retour de la fonction  dropDepth  supérieur à  0 .
 if (data.dropDepth> 0) return  Ceci est car même si l'événement  ondragleave  est déclenché, nous sommes toujours dans la zone A. Ce n'est qu'après avoir frappé  A-out  et  dropDepth  est maintenant  0  que nous avons défini  inDropZone  sur  false . À ce stade, nous avons laissé toutes les zones de dépôt.
 const handleDragOver = e => {
  ...
  e.dataTransfer.dropEffect = 'copier';
  dispatch ({type: 'SET_IN_DROP_ZONE', inDropZone: true});
};
 Chaque fois que cet événement se déclenche, nous définissons  inDropZone  sur  true . Cela nous indique que nous sommes à l'intérieur de la zone de largage. Nous avons également défini  dropEffect  sur l'objet  dataTransfer  sur  copie . Sur un Mac, cela a pour effet d'afficher un signe plus vert lorsque vous faites glisser un élément dans la zone de dépôt.
 const handleDrop = e => {
  ...
  laisser les fichiers = [...e.dataTransfer.files];
  
  if (files && files.length> 0) {
    const existingFiles = data.fileList.map (f => f.name)
    files = files.filter (f =>! existingFiles.includes (f.name))
    
    dispatch ({type: 'ADD_FILE_TO_LIST', fichiers});
    e.dataTransfer.clearData ();
    dispatch ({type: 'SET_DROP_DEPTH', dropDepth: 0});
    dispatch ({type: 'SET_IN_DROP_ZONE', inDropZone: false});
  }
};
 Nous pouvons accéder aux fichiers déposés avec  e.dataTransfer.files . La valeur est un objet de type tableau, nous utilisons donc la syntaxe d'étalement du tableau pour le convertir en un tableau  JavaScript .
 Nous devons maintenant vérifier s'il y a au moins un fichier avant d'essayer de l'ajouter à notre gamme de fichiers. Nous nous assurons également de ne pas inclure les fichiers qui se trouvent déjà dans notre  fileList .
 L'objet  dataTransfer  est effacé en préparation de la prochaine opération de glisser-déposer. Nous avons également réinitialisé les valeurs de  dropDepth  et  inDropZone .
 Mettez à jour le  className  de la  div  dans le  DragAndDrop  composant. Cela modifiera conditionnellement le  className  de la  div  en fonction de la valeur de  data.inDropZone .
 
   Faites glisser les fichiers ici pour les télécharger 
 Rendez la liste des fichiers dans  App.js  en mappant à travers  data.fileList .
 
   Composant React par glisser-déposer 
  
     {data.fileList.map (f => {
      revenir (
        -  {f.name} )
    })}
 Maintenant, essayez de faire glisser et de déposer certains fichiers dans la zone de dépôt. Vous verrez que lorsque nous entrons dans la zone de dépôt, l'arrière-plan devient moins opaque car la classe  inside-drag-area  est activée.
Lorsque vous relâchez les fichiers à l'intérieur de la zone de dépôt, vous voir les noms de fichiers répertoriés sous la zone de dépôt:


 La version complète de ce didacticiel se trouve dans la branche  04-finish-handlers . [19659089] Conclusion
 Nous avons vu comment gérer les téléchargements de fichiers dans React à l'aide de l'API  HTML  glisser-déposer. Nous avons également appris à gérer l'état avec le crochet  useReducer . Nous pourrions étendre la fonction du fichier  handleDrop . Par exemple, nous pourrions ajouter une autre vérification pour limiter la taille des fichiers si nous le voulions. Cela peut venir avant ou après la vérification des fichiers existants. Nous pourrions également rendre la zone de dépôt cliquable sans affecter la fonctionnalité de glisser-déposer.
Ressources
 (ra, ks, il)
 (ra, ks, il) Source link
