react-dnd:通过单击拖动后移动的don don'通过

发布于 2025-01-24 02:21:01 字数 5709 浏览 0 评论 0原文

我正在使用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.
current page

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文