Я настойчиво работал над этой проблемой, цель которой состоит в том, чтобы перетащить карточку из «Столбца 1» и скопировать ее в другой столбец, скажем, «Столбец 2». Теперь, когда моя первая карта перетаскивается и помещается в «Столбец 2», карта соответственно добавляется в этот столбец, но когда я перетаскиваю другую карту и помещаю ее в «Столбец 2» вместо добавления, она просто заменяет существующую карту собой. Я отлаживаю состояние, но проблема все еще сохраняется. Я не понял, что я здесь делаю не так?
Вот мой код
// Card Component
function Card({ id, text, isDrag }) {
const [, drag] = useDrag(() => ({
type: "bp-card",
item: () => {
return { id, text}
},
collect: monitor => ({
isDragging:!!monitor.isDragging(),
}),
canDrag: () => isDrag
}));
return (
<div
className='card'
ref={drag}
style={{
cursor: isDrag? 'pointer': 'no-drop'
}}
>
{text}
</div>
)
}
// Column Component
function Column({ title, children, onCardDropped }) {
const [, drop] = useDrop(() => ({
accept: "bp-card",
drop: item => {
onCardDropped(item);
}
}));
return (
<div className="flex-item" ref={title === 'Column 2'? drop: null}>
<p>{title}</p>
{children.length > 0 && children.map(({ id, text, isDrag }) => (
<Card
key={id}
id={id}
text={text}
isDrag={isDrag}
/>
))}
</div>
)
}
// Main App
function App() {
const [cards] = useState([
{ id: 1, text: 'Card 1', isDrag: true },
{ id: 2, text: 'Card 2', isDrag: true },
]);
const [columns, setColumns] = useState([
{
id: 1,
title: 'Column 1',
children: cards
},
{
id: 2,
title: 'Column 2',
children: []
},
]);
const onCardDropped = ({ id, text }) => {
// let card = null;
const targetColumnId = 2;
const transformedColumns = columns.map(column => {
if (column.id === targetColumnId) {
return {
...column,
children: [
...column.children,
{ id, text }
]
}
}
return column;
});
setColumns(transformedColumns);
}
return (
<DndProvider backend={HTML5Backend}>
<div className='flex-container'>
{columns.map((column) => (
<Column
key={column.id}
title={column.title}
children={column.children}
onCardDropped={onCardDropped}
/>
))}
</div>
</DndProvider>
);
}
Любая помощь высоко ценится. Спасибо.
Решение проблемы
Вам нужно учитывать предыдущее состояние, используя обратный вызов метода set state. Он начинает работать после изменения, onCardDropped
как показано ниже.
const onCardDropped = ({ id, text }) => {
// let card = null;
const targetColumnId = 2;
setColumns((prevColumns) =>
prevColumns.map((column) => {
if (column.id === targetColumnId) {
return {
...column,
children: [...column.children, { id, text }]
};
}
return column;
})
);
};
Всегда полезно использовать состояние из метода обратного вызова, а не напрямую использовать объект состояния, который может быть устаревшим.
Рабочая демонстрация
Комментариев нет:
Отправить комментарий