Как стать автором
Обновить

Комментарии 26

Спасибо! Как раз сейчас делаю «убийцу трелло» и думал над днд
Одно время была популярна библиотека Dragula, вроде бы. Она сейчас как? Уже не торт?
ведь теперь мы полностью продублировали код нашего превью в функции generatePlaceholder

Почему бы не использовать «renderToStaticMarkup»? Сам не пробовал, но вроде как у renderToStaticMarkup нет ограничений в использовании на клиенте.
Спасибо за комментарий! Обязательно попробую. Если заработает, то допишу в статье!)
Спасибо!) Поправил.
Чтобы избавится от лишних перерисовок реализуем метод shouldComponentUpdate в GridDragLayer. Для плавности нам нужно обеспечить 60fps, т.е. одна перерисовка на 16 мс.
Возможные «залипания», когда компонент изменил свое состояние в интервале 16 мс, но не был перерисован, устраняются таймером и forceUpdate.


А что действительно нет возможности не перерисовывать весь GridDragLayer? Я правильно этому ужасаюсь, или «так и должно быть», «иначе не сделаешь»? Оно моргать не будет? А на планшетке? Я когда писал расписания с драгндропами с jquery-ui selectable/draggable/droppable (сотни объектов) никаких проблем с производительностью не имел и вообще не задумвывался о fps. Что-то я как то не готов морально к такому прогрессу. Ободрите, что все тут ok.
GridDragLayer — маленькое прямоугольное превью, которое появляется только в момент перетаскивания, а не вся таблица с расписанием, как вы наверное подумали. Не моргает, скринкасты есть в статье.
А такие замечательные гифки ловящие курсор и ДнД чем делаются?
Можно в ScreenToGif, к примеру.
А что если получить элемент через ref и при движении менять ему стиль напрямую?

Кстати, чем не устроили свойства left и top? Неужели трансформации работают быстрее?
1. Данный вариант оказался проще в плане реализации (если учесть, что используется React DnD)
2. Если верить этой статье — www.paulirish.com/2012/why-moving-elements-with-translate-is-better-than-posabs-topleft то да. Сам тесты не проводил.

Хм, а что сложного? Третий параметр component у beginDrag — это ваш компонент. Пишем что-то вроде <div ref={el => this.div = el}> и можно обращаться к этому элементу как component.div вместо placeholder.

А что если в «секции» находится две пары и мы перемещаем одну из них? Плейсхолдер получится в 1/2 от обычной высоты и будет выглядеть не так эстетично)
Это вы вообще о чем?


А как вы решаете эту проблему при создании плейсхолдера? Просто задаете ему начальную высоту при создании, которое происходит при начале перетаскивания, не так ли?


А ведь то же самое можно и с рефом сделать...

Да, все верно, при создании плейсхолдера мы задаем ему стили.
Можно проделать все это и c рефом. Таким образом получаем два возможных решения одной задачи, которые по сути отличаются не сильно. Перетаскиваем div-блок изменяя через стили его позицию.

Хм, а в чем преимущества рендера в строку с последующим парсингом перед однократным вызовом ReactDOM.render?


Не пробовали вместо


  placeholder.innerHTML = ReactDOMServer.renderToStaticMarkup(<SubjectContent { ...item } />);

написать вот так:


  ReactDOM.render(<SubjectContent { ...item } />, placeholder);
Реализовал по совету Odrin, тем самым решив проблему с дублированием кода. Можно попробовать и ваш подход, но не думаю что это даст нам существенный прирост по производительности. Сам метод вызывается всего один раз для создания превью и не является узким местом) В любом случае спасибо!)
Недавно работал тоже была необходимость в Drag&Drop. Использовал вот это github.com/danielstocks/react-sortable (простенькая и ничего лишнего)

Не совсем понял из статьи и из комментариев, почему нельзя оптимизировать перерисовку компонента до обновления только свойств top и left (или transform)?

В варианте с GridDragLayer так и было, но результат получился не очень. Без троттлинга работало вполне себе, а с CPU 4x slowdown пошли фризы.

Не вижу там shouldComponentUpdate. Мне кажется, можно было бы реализовать его и проверять, изменились ли данные, возвращаемые monitor (а предыдущие сохранять в стейте, например).


Или, как вариант, возвращать true из shouldComponentUpdate каждые 16мс.
forceUpdate, как по мне, не выглядит правильным решением.

Он в «Листинг shouldComponentUpdate»
Спасибо! Можно забыть про jQuery UI Draggable и Droppable
Зарегистрируйтесь на Хабре , чтобы оставить комментарий