react-dnd helloworld

参考文档: https://react-dnd.github.io/react-dnd/examples-sortable-simple.html

核心理解:
1.ItemTypes.CARD, cardTarget, connect
第一个参数是类型,第二个参数是 事件注册,第三个参数是个函数,返回值要注入到组件总的内容

2.beginDrag 的返回值,可以理解为原生的(dataTransfer.setData),设置拖动的数据,传递给hover中使用,(monitor.getItem().index)

3.使用了ES7 的decorator

“`
import React, { Component, PropTypes } from ‘react’;
import { findDOMNode } from ‘react-dom’;
import { DragSource, DropTarget } from ‘react-dnd’;
import ItemTypes from ‘./ItemTypes’;

const style = {
border: ‘1px dashed gray’,
padding: ‘0.5rem 1rem’,
marginBottom: ‘.5rem’,
backgroundColor: ‘white’,
cursor: ‘move’,
};

// dnd 生命的对象 拖动源
const cardSource = {
// 开始拖动
beginDrag(props) {
//monitor.getItem() 的对象
return {
id: props.id,
index: props.index,
};
},
};

// 拖动目标 事件
const cardTarget = {
// hover
// props 当前组件的属性
// monitor 拖动中的对象
// componet 当前组件

hover(props, monitor, component) {

    // 当前拖动的index
    const dragIndex = monitor.getItem().index;

    // 当前hover 的index
    const hoverIndex = props.index;

    // Don't replace items with themselves
    if (dragIndex === hoverIndex) {
        return;
    }

    // Determine rectangle on screen
    const hoverBoundingRect = findDOMNode(component).getBoundingClientRect();

    // Get vertical middle
    const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;

    // Determine mouse position
    const clientOffset = monitor.getClientOffset();

    // Get pixels to the top
    const hoverClientY = clientOffset.y - hoverBoundingRect.top;

    // Only perform the move when the mouse has crossed half of the items height
    // When dragging downwards, only move when the cursor is below 50%
    // When dragging upwards, only move when the cursor is above 50%

    // Dragging downwards
    if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {
        return;
    }

    // Dragging upwards
    if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
        return;
    }

    // Time to actually perform the action
    props.moveCard(dragIndex, hoverIndex);

    // Note: we're mutating the monitor item here!
    // Generally it's better to avoid mutations,
    // but it's good here for the sake of performance
    // to avoid expensive index searches.
    // 新的位置
    monitor.getItem().index = hoverIndex;
},

};

// 声明放下
@DropTarget(ItemTypes.CARD, cardTarget, connect => ({
connectDropTarget: connect.dropTarget(),
}))
// 声明拖动 第三个参数 返回值会注入到对象中
@DragSource(ItemTypes.CARD, cardSource, (connect, monitor) => ({
connectDragSource: connect.dragSource(),
isDragging: monitor.isDragging(),
}))
export default
class Card extends Component {
static propTypes = {
connectDragSource: PropTypes.func.isRequired,
connectDropTarget: PropTypes.func.isRequired,
index: PropTypes.number.isRequired,
isDragging: PropTypes.bool.isRequired,
id: PropTypes.any.isRequired,
text: PropTypes.string.isRequired,
moveCard: PropTypes.func.isRequired,
};

render() {

    //   isDragging, connectDragSource, connectDropTarget  是 注入的
    // text 是父亲传递进来的
    const { text, isDragging, connectDragSource, connectDropTarget } = this.props;


    // 是否是isDragging
    const opacity = isDragging ? 0 : 1;

    return connectDragSource(connectDropTarget(
        <div style={{ ...style, opacity }}>
            {text}
        </div>,
    ));
}

}

“`

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
React DnD 是一个 React 的拖放库,可以帮助我们快速实现拖放功能。下面是一个基本的示例: 首先,安装 `react-dnd` 和 `react-dnd-html5-backend`: ``` npm install react-dnd react-dnd-html5-backend ``` 然后,创建一个拖放组件: ```jsx import React from 'react'; import { useDrag } from 'react-dnd'; const Box = ({ name }) => { const [{ isDragging }, drag] = useDrag({ item: { name, type: 'box' }, collect: (monitor) => ({ isDragging: !!monitor.isDragging(), }), }); return ( <div ref={drag} style={{ opacity: isDragging ? 0.5 : 1, fontSize: 20, fontWeight: 'bold', cursor: 'move', }} > {name} </div> ); }; export default Box; ``` 在上面的代码中,我们使用 `useDrag` 钩子来创建一个拖动源。`item` 属性指定了拖动源的参数,`collect` 函数用于收集拖动源的状态。 接下来,创建一个拖放目标组件: ```jsx import React from 'react'; import { useDrop } from 'react-dnd'; const Target = ({ onDrop }) => { const [{ isOver }, drop] = useDrop({ accept: 'box', drop: (item, monitor) => { onDrop(item); }, collect: (monitor) => ({ isOver: !!monitor.isOver(), }), }); return ( <div ref={drop} style={{ width: 200, height: 200, backgroundColor: isOver ? 'yellow' : 'white', }} /> ); }; export default Target; ``` 在上面的代码中,我们使用 `useDrop` 钩子来创建一个拖放目标。`accept` 属性指定了接受的拖动源类型,`drop` 函数用于处理拖放事件,`collect` 函数用于收集拖放目标的状态。 最后,在父组件中使用这两个组件: ```jsx import React, { useState } from 'react'; import Box from './Box'; import Target from './Target'; const App = () => { const [droppedBox, setDroppedBox] = useState(null); const handleDrop = (item) => { setDroppedBox(item.name); }; return ( <div> <Box name="Box 1" /> <Box name="Box 2" /> <Box name="Box 3" /> <Target onDrop={handleDrop} /> {droppedBox && <p>Dropped box: {droppedBox}</p>} </div> ); }; export default App; ``` 在上面的代码中,我们使用 `useState` 钩子来保存拖放目标接受的拖动源名称。`handleDrop` 函数用于处理拖放事件,并更新状态。最后,我们在页面上显示拖放的结果。 这就是一个简单的 React DnD 示例。如果想要了解更多内容,可以查看官方文档:https://react-dnd.github.io/react-dnd/docs/overview。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值