Я успешно реализовал Beautiful DnD в приложении React, где перетаскиваемыми элементами являются Панели расширения пользовательского интерфейса материала. У меня есть список элементов, обращающихся к onDragEnd и сохраняющих новый отсортированный список в состоянии.
Я использую перехватчики React, useState, Панель расширения Material-UI и React-Beautiful-DnD.
Когда эта часть приложения загружается, первая панель расширения раскрывается, а все остальные свертываются.
То, что я пытался заставить работать, - это как закрыть панель расширения [onDragStart | onBeforeDragStart | onDragUpdate], а затем откройте панель расширения onDragEnd.
Я сохранил состояние каждой панели расширения вместе с другой информацией в массиве, который зацикливается и отображает каждую панель расширения: {name: string, extended: string, ...}
Я думаю, что это проблема, когда состояние не обновляется, когда панель расширения не принимает изменения.
Я пытался использовать снимок .isDragging на элементе, чтобы изменить расширенное состояние панелей расширения и даже попытался нацелиться на указанную панель расширения c, найти соответствующий элемент в списке состояний и обновить расширенную реквизит onDragStart, onBeforeDragStart и onDragUpdate. Пока что ни один из них не сработал.
Вот часть компонента, обрабатывающего DnD
const newArray = ReorderList(srcList, ixSelectedItem, 0);
const panelState: Array<ExpansionState> = [];
// eslint-disable-next-line array-callback-return
newArray.map(item => {
panelState.push({
name: item as string,
expanded: item === selectedItem,
isDragging: false
});
});
const [itemListWithState, setItemListWithState] = useState(panelState);
const handleOnDragEnd = (result: any): void => {
const { destination, draggableId, source } = result;
if (!destination) {
return;
}
if (destination.droppableId === source.droppableId && destination.index === source.index) {
return;
}
const newList = ReorderList(itemListWithState, source.index, destination.index) as Array<ExpansionState>;
const ix = newList.findIndex(item => item.name === draggableId);
newList[ix].isDragging = false;
newList[ix].expanded = !newList[ix].expanded;
setItemListWithState(newList);
};
const handleOnDragUpdate = (result: any): void => {
const { draggableId } = result;
const ix = itemListWithState.findIndex(item => item.name === draggableId);
if (!itemListWithState[ix].isDragging) {
itemListWithState[ix].expanded = !itemListWithState[ix].expanded;
itemListWithState[ix].isDragging = true;
}
};
...
...
return (
<DragDropContext onDragEnd={handleOnDragEnd} onDragUpdate={handleOnDragUpdate}>
<Droppable droppableId="list">
{(provided, snapshot) => {
return (
<div ref={provided.innerRef} {...provided.droppableProps}>
{itemListWithState.map((item: ExpansionState, index: number) => {
return (
<Draggable key={item.name} draggableId={item.name} index={index}>
{(provided, snapshot) => {
return (
<div ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>
<GraphContainer id={item.name} isGraphExpanded={item.expanded} {...props}></GraphContainer>
</div>
);
}}
</Draggable>
);
})}
{provided.placeholder}
</div>
);
}}
</Droppable>
</DragDropContext>
);
Вот компонент, в котором находится панель расширения:
return (
<div style={{ margin: '20px 0' }}>
<Panel
expanded={props.isGraphExpanded}
summaryTitle={getResourceString(props.id, Resources.Performance)}
summaryDetail={props.graph}
isDraggable={true}
subPanel={
<Panel
expanded={false}
summaryTitle={getResourceString(props.id, Resources.DataTable)}
summaryDetail={props.table}
isDraggable={false}
></Panel>
}
></Panel>
</div>
);