react-dnd:通过单击拖动后移动的don don'通过
我正在使用React-DND模块实现拖放组件。 功能是通过拖动项目和单击箭头按钮在两个板之间移动项目。
现在单击效果很好。但是,在拖动一些项目后,当我通过单击箭头按钮移动项目时,它返回已经通过再次拖动移动项目。 请帮助我解决这个问题。 这是我的组件。
<Container>
<Row>
<Column width={5}>
<Board
source="role"
destination="system"
items={permissions}
onClickItems={onClickItem}
active={selectedItemKey === 'system'}
onDraggingEnd={handleDragginEnd}
/>
</Column>
<Column width={2}>
<div className="d-flex justify-content-center h-100">
<ButtonGroup className="my-auto" screenReaderLabel="Set manager controls">
<Button variant="dark" onClick={handleMoveLeft}>
<BootstrapIcon icon="arrow-left" />
</Button>
<Button className="disabled" variant="link" disabled />
<Button variant="dark" onClick={handleMoveRight}>
<BootstrapIcon icon="arrow-right" />
</Button>
</ButtonGroup>
</div>
</Column>
<Column width={5}>
<Board
source="system"
destination="role"
items={systemPermissions}
onClickItems={onClickItem}
active={selectedItemKey === 'role'}
onDraggingEnd={handleDragginEnd}
/>
</Column>
</Row>
</Container>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.0.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.0.0/umd/react-dom.production.min.js"></script>
import React, { useEffect, useRef, useState } from 'react';
import { Permission } from '@domain/data/Permission';
import Item from '@components/compositions/data/dnd/Item';
import { useDrop } from 'react-dnd';
type Props = {
source: string;
items: Array<Permission>;
destination: string;
active: boolean;
onClickItems: (id: string, source: string) => void;
onDraggingEnd: (boardKey: string, dragginItemId: string) => void;
};
const Board = (props: Props) => {
const { source, items, destination, active, onClickItems, onDraggingEnd } = props;
const [permissions, setPermissions] = useState<Array<Permission>>([]);
const [selectedItemId, setSelectedItemId] = useState<string | null>();
const dropFunction = (item: Permission) => {
setPermissions((value: Array<Permission>) => {
if (value.filter(node => node.id === item.id).length === 0) {
return [...value, item];
} else {
return value;
}
});
setSelectedItemId(null);
};
useEffect(() => {
setPermissions(items);
}, [items]);
const [{ isOver }, dropRef] = useDrop({
accept: source,
drop: dropFunction,
collect: monitor => ({
isOver: monitor.isOver()
})
});
const handleDragEnd = (item: Permission) => {
const filteredPermissions = permissions.filter(node => node.id !== item.id);
setPermissions(filteredPermissions);
onDraggingEnd(destination, item.id);
setSelectedItemId(null);
};
const handleClickItem = (clickedId: string, source: string) => {
setSelectedItemId(clickedId);
onClickItems(clickedId, source);
};
return (
<React.Fragment>
<div className="basket" style={{ backgroundColor: 'yellow', minHeight: 50 }} ref={dropRef}>
{permissions.map((permission: Permission) => (
<Item
key={permission.id}
id={permission.id}
name={permission.name}
destination={destination}
active={active && permission.id === selectedItemId}
onDragEnd={handleDragEnd}
onClickItem={handleClickItem}
/>
))}
{isOver && <div>Drop Here!</div>}
</div>
</React.Fragment>
);
};
export default Board;
import React from 'react'
import { useDrag } from 'react-dnd';
import ListGroupItem from '@components/blocks/lists/ListGroupItem';
type Props = {
id: string;
name: string;
destination: string;
active: boolean;
onDragEnd: (item: any) => void;
onClickItem: (id: string, code: string) => void;
}
const Item = (props: Props) => {
const { id, name, destination, active, onDragEnd, onClickItem } = props;
const [{ isDragging }, dragRef] = useDrag({
type: destination,
item: { id, name },
end: (draggedItem, monitor) => {
if (monitor.didDrop()) {
onDragEnd && onDragEnd(draggedItem);
}
},
collect: (monitor) => ({
isDragging: monitor.isDragging()
})
})
return (
<div className='dnd-item' ref={dragRef} onClick={() => onClickItem(id, destination)}>
<ListGroupItem active={active}>
{name}
{isDragging && '
I am implementing Drag and Drop component using React-dnd module.
Features are moving items between two boards by dragging items and by clicking arrow buttons.
Now clicking works well. But after dragging some items, when I move item by clicking arrow button, it returns already moved items by dragging again.
Please help me to fix this problem.
Here are my components.
<Container>
<Row>
<Column width={5}>
<Board
source="role"
destination="system"
items={permissions}
onClickItems={onClickItem}
active={selectedItemKey === 'system'}
onDraggingEnd={handleDragginEnd}
/>
</Column>
<Column width={2}>
<div className="d-flex justify-content-center h-100">
<ButtonGroup className="my-auto" screenReaderLabel="Set manager controls">
<Button variant="dark" onClick={handleMoveLeft}>
<BootstrapIcon icon="arrow-left" />
</Button>
<Button className="disabled" variant="link" disabled />
<Button variant="dark" onClick={handleMoveRight}>
<BootstrapIcon icon="arrow-right" />
</Button>
</ButtonGroup>
</div>
</Column>
<Column width={5}>
<Board
source="system"
destination="role"
items={systemPermissions}
onClickItems={onClickItem}
active={selectedItemKey === 'role'}
onDraggingEnd={handleDragginEnd}
/>
</Column>
</Row>
</Container>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.0.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.0.0/umd/react-dom.production.min.js"></script>
import React, { useEffect, useRef, useState } from 'react';
import { Permission } from '@domain/data/Permission';
import Item from '@components/compositions/data/dnd/Item';
import { useDrop } from 'react-dnd';
type Props = {
source: string;
items: Array<Permission>;
destination: string;
active: boolean;
onClickItems: (id: string, source: string) => void;
onDraggingEnd: (boardKey: string, dragginItemId: string) => void;
};
const Board = (props: Props) => {
const { source, items, destination, active, onClickItems, onDraggingEnd } = props;
const [permissions, setPermissions] = useState<Array<Permission>>([]);
const [selectedItemId, setSelectedItemId] = useState<string | null>();
const dropFunction = (item: Permission) => {
setPermissions((value: Array<Permission>) => {
if (value.filter(node => node.id === item.id).length === 0) {
return [...value, item];
} else {
return value;
}
});
setSelectedItemId(null);
};
useEffect(() => {
setPermissions(items);
}, [items]);
const [{ isOver }, dropRef] = useDrop({
accept: source,
drop: dropFunction,
collect: monitor => ({
isOver: monitor.isOver()
})
});
const handleDragEnd = (item: Permission) => {
const filteredPermissions = permissions.filter(node => node.id !== item.id);
setPermissions(filteredPermissions);
onDraggingEnd(destination, item.id);
setSelectedItemId(null);
};
const handleClickItem = (clickedId: string, source: string) => {
setSelectedItemId(clickedId);
onClickItems(clickedId, source);
};
return (
<React.Fragment>
<div className="basket" style={{ backgroundColor: 'yellow', minHeight: 50 }} ref={dropRef}>
{permissions.map((permission: Permission) => (
<Item
key={permission.id}
id={permission.id}
name={permission.name}
destination={destination}
active={active && permission.id === selectedItemId}
onDragEnd={handleDragEnd}
onClickItem={handleClickItem}
/>
))}
{isOver && <div>Drop Here!</div>}
</div>
</React.Fragment>
);
};
export default Board;
import React from 'react'
import { useDrag } from 'react-dnd';
import ListGroupItem from '@components/blocks/lists/ListGroupItem';
type Props = {
id: string;
name: string;
destination: string;
active: boolean;
onDragEnd: (item: any) => void;
onClickItem: (id: string, code: string) => void;
}
const Item = (props: Props) => {
const { id, name, destination, active, onDragEnd, onClickItem } = props;
const [{ isDragging }, dragRef] = useDrag({
type: destination,
item: { id, name },
end: (draggedItem, monitor) => {
if (monitor.didDrop()) {
onDragEnd && onDragEnd(draggedItem);
}
},
collect: (monitor) => ({
isDragging: monitor.isDragging()
})
})
return (
<div className='dnd-item' ref={dragRef} onClick={() => onClickItem(id, destination)}>
<ListGroupItem active={active}>
{name}
{isDragging && '????'}
</ListGroupItem>
</div>
)
}
export default Item;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论