Java, UX, HTML, CSS, WEB-design

Как использовать API перетаскивания HTML в React

[ad_1]

  • Чиди Орджи

  • 0 Комментарии

Как использовать API перетаскивания HTML в React

  • 9 минут чтения

  • API, Реагировать, JavaScript

Краткое резюме ↬

В этом руководстве мы создадим компонент перетаскивания React для загрузки файлов и изображений. В процессе мы узнаем об API перетаскивания HTML. Мы также узнаем, как использовать хук useReducer для управления состоянием в функциональном компоненте React.

API перетаскивания — одна из самых крутых функций HTML. Это помогает нам реализовать функции перетаскивания в веб-браузерах.

В текущем контексте мы будем перетаскивать файлы из-за пределов браузера. При удалении файлов мы помещаем их в список и отображаем их имена. Имея файлы на руках, мы могли бы затем выполнить какую-либо другую операцию с файлами, например, загрузить их на облачный сервер.

В этом руководстве мы сосредоточимся на том, как реализовать действие перетаскивания в приложении React. Если вам нужна простая JavaScript реализации, возможно, вы сначала захотите прочитать «Как сделать загрузчик файлов с помощью перетаскивания с помощью ванильного JavaScript», отличный учебник, написанный Джозефом Циммерманом не так давно.

То dragenter, dragleave, dragover, И drop События

Существует восемь различных событий перетаскивания. Каждый из них срабатывает на разных этапах операции перетаскивания. В этом уроке мы сосредоточимся на четырех, которые срабатывают, когда предмет попадает в зону сброса: dragenter, dragleave, dragover и drop.

  1. То dragenter событие срабатывает, когда перетаскиваемый элемент попадает в допустимую цель перетаскивания.
  2. То dragleave событие срабатывает, когда перетаскиваемый элемент покидает допустимую цель перетаскивания.
  3. То dragover событие срабатывает, когда перетаскиваемый элемент перетаскивается по допустимой цели перетаскивания. (Он срабатывает каждые несколько сотен миллисекунд.)
  4. То drop событие срабатывает, когда элемент падает на допустимую цель перетаскивания, т.е. перетаскивается и отпускается.

Мы можем превратить любой HTML-элемент в допустимую цель перетаскивания, определив ondragover и ondrop атрибуты обработчика событий.

Вы можете узнать все о восьми событиях из веб-документов MDN.

Еще после прыжка! Продолжить чтение ниже ↓

События перетаскивания в React

Для начала клонируйте репозиторий учебника по этому URL-адресу:

https://github.com/chidimo/react-dnd.git

Проверьте 01-start филиал. Убедитесь, что у вас есть yarn также установлен. Вы можете получить его на сайте yarnpkg.com.

Но если хотите, создайте новый проект React и замените содержимое App.js с кодом ниже:

import React from 'react';
import './App.css';

function App() {
  return (
    <div className="App">
      <h1>React drag-and-drop component</h1>
    </div>
  );
}
export default App;

Также замените содержимое App.css с приведенным ниже стилем CSS:

.App {
  margin: 2rem;
  text-align: center;
}
h1 {
  color: #07F;
}
.drag-drop-zone {
  padding: 2rem;
  text-align: center;
  background: #07F;
  border-radius: 0.5rem;
  box-shadow: 5px 5px 10px #C0C0C0;
}
.drag-drop-zone p {
  color: #FFF;
}
.drag-drop-zone.inside-drag-area {
  opacity: 0.7;
}
.dropped-files li {
  color: #07F;
  padding: 3px;
  text-align: left;
  font-weight: bold;
}

Если вы клонировали репозиторий, введите следующие команды (по порядку), чтобы запустить приложение:

yarn # install dependencies
yarn start # start the app

Следующим шагом является создание компонента перетаскивания. Создать файл DragAndDrop.js внутри src/ папка. Введите следующую функцию внутри файла:

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();
  };
  return (
    <div className={'drag-drop-zone'}
      onDrop={e => handleDrop(e)}
      onDragOver={e => handleDragOver(e)}
      onDragEnter={e => handleDragEnter(e)}
      onDragLeave={e => handleDragLeave(e)}
    >
      <p>Drag files here to upload</p>
    </div>
  );
};
export default DragAndDrop;

В ответ div, мы определили наш фокус HTML атрибуты обработчика событий. Вы можете видеть, что единственное отличие от чистого HTML это верблюжья оболочка.

То div теперь является допустимой целью перетаскивания, так как мы определили onDragOver и onDrop атрибуты обработчика событий.

Мы также определили функции для обработки этих событий. Каждая из этих функций-обработчиков получает объект события в качестве аргумента.

Для каждого из обработчиков событий мы вызываем preventDefault() чтобы браузер не выполнял поведение по умолчанию. Браузер по умолчанию открывает перетащенный файл. Мы также звоним stopPropagation() чтобы убедиться, что событие не распространяется от дочерних элементов к родительским.

Импортировать DragAndDrop компонент в App компонент и визуализировать его под заголовком.

<div className="App">
  <h1>React drag-and-drop component</h1>
  <DragAndDrop />
</div>

Теперь просмотрите компонент в браузере, и вы должны увидеть что-то вроде изображения ниже.

Зона сброса

div для превращения в зону сброса (большой превью)

Если вы следите за репо, соответствующая ветка 02-start-dragndrop

Управление состоянием с помощью useReducer Крюк

Нашим следующим шагом будет написание логики для каждого из наших обработчиков событий. Прежде чем мы это сделаем, мы должны подумать, как мы собираемся отслеживать удаленные файлы. Здесь мы начинаем думать об управлении состоянием.

Мы будем отслеживать следующие состояния во время операции перетаскивания:

  1. dropDepth

    Это будет целое число. Мы будем использовать его, чтобы отслеживать, на сколько уровней мы находимся в зоне сброса. Позже я объясню это иллюстрацией. (Спасибо Егору Егорову за то, что он пролил на меня свет!)

  2. inDropZone

    Это будет логическое значение. Мы будем использовать это, чтобы отслеживать, находимся ли мы внутри зоны сброса или нет.

  3. FileList

    Это будет список. Мы будем использовать его для отслеживания файлов, которые были перемещены в зону сброса.

Для обработки состояний React предоставляет useState и useReducer крючки. Мы выберем useReducer ловушку, учитывая, что мы будем иметь дело с ситуациями, когда состояние зависит от предыдущего состояния.

То useReducer крючок принимает редуктор типа (state, action) => newStateи возвращает текущее состояние в паре с dispatch метод.

Вы можете прочитать больше о useReducer в документации React.

Внутри App компонент (перед return оператор), добавьте следующий код:

...
const reducer = (state, action) => {
  switch (action.type) {
    case 'SET_DROP_DEPTH':
      return { ...state, dropDepth: action.dropDepth }
    case 'SET_IN_DROP_ZONE':
      return { ...state, inDropZone: action.inDropZone };
    case 'ADD_FILE_TO_LIST':
      return { ...state, fileList: state.fileList.concat(action.files) };
    default:
      return state;
  }
};
const [data, dispatch] = React.useReducer(
  reducer, { dropDepth: 0, inDropZone: false, fileList: [] }
)
...

То useReducer крючок принимает два аргумента: редьюсер и начальное состояние. Возвращает текущее состояние и dispatch функция, с помощью которой можно обновить состояние. Состояние обновляется путем отправки действия, содержащего type и дополнительная полезная нагрузка. Обновление состояния компонента зависит от того, что возвращается оператором case в результате типа действия. (Обратите внимание, что наше начальное состояние object.)

Для каждой из переменных состояния мы определили соответствующий оператор case для ее обновления. Обновление выполняется путем вызова dispatch функция, возвращаемая useReducer.

Теперь пройти data и dispatch в виде props к DragAndDrop компонент, который у вас есть в вашем App.js файл:

<DragAndDrop data={data} dispatch={dispatch} />

В верхней части DragAndDrop компонент, мы можем получить доступ к обоим значениям из props.

const { data, dispatch } = props;

Если вы следите за репо, соответствующая ветка 03-define-reducers.

Давайте закончим логику наших обработчиков событий. Обратите внимание, что многоточие представляет собой две строки:

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 });
  if (data.dropDepth > 0) return
  dispatch({ type: 'SET_IN_DROP_ZONE', inDropZone: false })
};

На приведенном ниже рисунке у нас есть вложенные зоны перетаскивания A и B. A — это наша интересующая нас зона. Здесь мы хотим прослушивать события перетаскивания.

Иллюстрация событий ondragenter и ondragleave

Иллюстрация ondragenter и ondragleave события (большой предварительный просмотр)

При перетаскивании в зону перетаскивания каждый раз, когда мы сталкиваемся с границей, ondragenter событие запущено. Это происходит на границах A-in и B-in. Так как мы входим в зону, мы увеличиваем dropDepth.

Аналогично, при перетаскивании из зоны перетаскивания каждый раз, когда мы сталкиваемся с границей, ondragleave событие запущено. Это происходит на границах A-out и B-out. Поскольку мы покидаем зону, мы уменьшаем значение dropDepth. Обратите внимание, что мы не устанавливаем inDropZone к false на границе B-out. Вот почему у нас есть эта строка для проверки dropDepth и возврата из функции dropDepth лучше чем 0.

if (data.dropDepth > 0) return

Это связано с тем, что, хотя ondragleave событие запущено, мы все еще в зоне A. Только после того, как мы нажмем A-out, и dropDepth сейчас 0 что мы установили inDropZone к false. На данный момент мы покинули все зоны сброса.

const handleDragOver = e => {
  ...
  e.dataTransfer.dropEffect="copy";
  dispatch({ type: 'SET_IN_DROP_ZONE', inDropZone: true });
};

Каждый раз, когда это событие срабатывает, мы устанавливаем inDropZone к true. Это говорит нам о том, что мы находимся внутри зоны сброса. Мы также установили dropEffect на dataTransfer Возражать copy. На Mac это приводит к отображению зеленого знака плюса при перетаскивании элемента в зоне перетаскивания.

const handleDrop = e => {
  ...
  let files = [...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', files });
    e.dataTransfer.clearData();
    dispatch({ type: 'SET_DROP_DEPTH', dropDepth: 0 });
    dispatch({ type: 'SET_IN_DROP_ZONE', inDropZone: false });
  }
};

Мы можем получить доступ к удаленным файлам с помощью e.dataTransfer.files. Значение представляет собой объект, подобный массиву, поэтому мы используем синтаксис распространения массива, чтобы преобразовать его в JavaScript множество.

Теперь нам нужно проверить, есть ли хотя бы один файл, прежде чем пытаться добавить его в наш массив файлов. Мы также следим за тем, чтобы не включать файлы, которые уже находятся на нашем fileList. То dataTransfer объект очищается при подготовке к следующей операции перетаскивания. Мы также сбрасываем значения dropDepth и inDropZone.

Обновите className принадлежащий div в DragAndDrop компонент. Это условно изменит className принадлежащий div в зависимости от значения data.inDropZone.

<div className={data.inDropZone ? 'drag-drop-zone inside-drag-area' : 'drag-drop-zone'}
      ...
    >
  <p>Drag files here to upload</p>
</div>

Отобразить список файлов в App.js путем сопоставления через data.fileList.

<div className="App">
  <h1>React drag-and-drop component</h1>
  <DragAndDrop data={data} dispatch={dispatch} />
  <ol className="dropped-files">
    {data.fileList.map(f => {
      return (
        <li key={f.name}>{f.name}</li>
      )
    })}
  </ol>
</div>

Теперь попробуйте перетащить несколько файлов в зону перетаскивания. Вы увидите, что когда мы входим в зону сброса, фон становится менее непрозрачным, потому что inside-drag-area класс активирован.

Когда вы освободите файлы внутри зоны сброса, вы увидите имена файлов, перечисленные под зоной сброса:

Зона перетаскивания с низкой прозрачностью во время перетаскивания

Зона перетаскивания показывает низкую непрозрачность во время перетаскивания (большой предварительный просмотр)

Список файлов, сброшенных в зону сброса

Список файлов, сброшенных в зону перетаскивания (большой превью)

Полная версия этого руководства находится на 04-finish-handlers филиал.

Вывод

Мы увидели, как обрабатывать загрузку файлов в React с помощью HTML API перетаскивания. Мы также узнали, как управлять состоянием с помощью useReducer крюк. Мы могли бы расширить файл handleDrop функция. Например, мы могли бы добавить еще одну проверку для ограничения размеров файлов, если бы захотели. Это может произойти до или после проверки существующих файлов. Мы также могли бы сделать зону перетаскивания кликабельной, не затрагивая функциональность перетаскивания.

Ресурсы

  • «Справочник по API хуков: useReducer», Реагировать Документы
  • «HTML Drag-and-Drop API», веб-документы MDN
  • «Примеры веб-разработки и XML-разработки с использованием DOM», веб-документы MDN
  • «Как сделать загрузчик файлов с помощью перетаскивания с помощью ванильного JavaScript», Джозеф Циммерман, Smashing Magazine
  • «Простая загрузка файлов перетаскиванием в React», Егор Егоров, Medium
Сокрушительная редакция
(ра, кс, иль)



[ad_2]
Source: https://smashingmagazine.com

Заключение

Вы ознакомились с статьей — Как использовать API перетаскивания HTML в React

Пожалуйста оцените статью, и напишите комментарий.

Похожие статьи

Добавить комментарий

Ваш адрес email не будет опубликован.

Краткое описание по статье Как использовать API перетаскивания HTML в React

Название: Как использовать API перетаскивания HTML в React . Краткое описание: [ad_1] ⭐ Чиди Ор . Дата публикации: 21.01.2022 . Автор: Алишер Валеев .

Для чего создан сайт Novosti-Nedeli.ru

Данный сайт посвящен новостям мира и мира технологий . Также тут вы найдете руководства по различным девайсам.

Сколько лет сайту?

Возраст составляет 3 года

Кнопка «Наверх»