Кто-нибудь может посоветовать лучший способ интеграции 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 не перерисовывалось правильно (если вы не обновляете), это было виновником.