Кто-нибудь может посоветовать лучший способ интеграции React Drag/Drop Lists с динамическими значениями из Redux?

Мне нужен компонент сортируемого перетаскивания, чтобы можно было повторно выполнить рендеринг с новыми значениями при нажатии кнопки пользователем из другого контейнера и при этом сохранить функциональность перетаскивания. Если список сначала содержит [a, b, c], мне нужно, чтобы он по-прежнему работал, когда пользователь нажимает кнопку, которая, например, повторно отображает список как [d, e, f, g].

Я сталкиваюсь с той же проблемой с react-sortable-hoc, react-beautiful-dnd и некоторые другие. Все эти библиотеки используют массив для заполнения их компонента списка перетаскивания, обычно называемого this.state.items в основных примерах. Они используют функцию под названием onSortEnd заниматься перестановкой предметов. Ниже приведен основной пример кода для Reaction-sortable-hoc, включающий мое обновление this.state.items в render():

import React, {Component} from 'react';
import {render} from 'react-dom';
import {SortableContainer, SortableElement, arrayMove} from 'react-sortable-hoc';

const SortableItem = SortableElement(({value}) =>
  <li>{value}</li>
);

const SortableList = SortableContainer(({items}) => {
  return (
    <ul>
      {items.map((value, index) => (
        <SortableItem key={`item-${index}`} index={index} value={value} />
      ))}
    </ul>
  );
});

class SelectedItem extends Component {
  state = {
    items: ['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5', 'Item 6'],
  };
  onSortEnd = ({oldIndex, newIndex}) => {
    this.setState({
      items: arrayMove(this.state.items, oldIndex, newIndex),
    });
  };
  render() {

// MY CODE ADDITIONS!! THIS IS WHERE THE LIST ITEM GETS UPDATED.

    this.state.items = [this.props.selectedItem.node.title,
                this.props.selectedItem.node.subtitle,
                this.props.selectedItem.treeIndex]; 

     return <SortableList items={this.state.items} onSortEnd={this.onSortEnd} />;
  }
}

function mapStateToProps(state)
{
    return {
        selectedItem: state.activeItem
    };
}

export default connect(mapStateToProps)(SelectedItem);

Сначала все отлично работает с перетаскиванием. Однако, если я изменю значение items[] в render(), новый список правильно отображает. Однако перетаскивание не удается. Похоже, это будет работать при перетаскивании; выбранный элемент перемещается, и целевое местоположение выглядит так, как будто оно его примет, но в onMouseRelease все возвращается к исходному.

Я поместил console.log команды после перемещения массива, чтобы убедиться, что список в items переупорядочивается по желанию. Это просто не происходит визуально. Там нет ошибки консоли при перетаскивании.

Любая помощь будет оценена.

1 ответ

Я решил это, используя getDerivedStateFromProps Метод жизненного цикла для обновления состояния элементов.

Я просто решил это, изменив атрибут Draggable key из этого формата:dragItem-${index} к этому: dragItem-${item.id}. Идентификатор для каждого элемента уникален, поэтому кажется, что это позволяет обновлять и отображать вещи правильно. Из документации по реакции (https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html):

При изменении ключа React создаст новый экземпляр компонента, а не обновит текущий.

Я мог видеть, что мое состояние обновлялось правильно, но что-то с response +beautiful-dnd не перерисовывалось правильно (если вы не обновляете), это было виновником.

Другие вопросы по тегам