ReactDnD技术疑问:如何获取beginDrag返回对象及connectDropTarget组件内的this?
ReactDnD 相关问题解答
1. 如何获取 beginDrag 方法返回的对象?
这个由拖拽源(DragSource)在beginDrag里返回的对象(我们通常叫它item),是在**拖拽目标(DropTarget)**的核心回调方法里获取的,比如drop、hover这些阶段。具体来说,你可以通过回调参数里的monitor.getItem()来拿到它。
举个类组件的例子:
import { DropTarget } from 'react-dnd'; // 定义拖拽目标的配置 const dropTargetSpec = { drop(props, monitor) { // 这里的 draggedItem 就是 beginDrag 返回的对象 const draggedItem = monitor.getItem(); console.log('拖拽过来的内容:', draggedItem); // 后续可以做状态更新、逻辑处理等操作 }, hover(props, monitor) { // 拖拽悬停阶段也能通过同样方式拿到对象 const currentDraggedItem = monitor.getItem(); } }; // 省略收集函数与组件定义...
如果是用函数组件搭配hooks,直接用useDrop钩子会更直观,回调里的第一个参数就是beginDrag返回的对象:
import { useDrop } from 'react-dnd'; function MyDropComponent() { const [{ isOver }, dropRef] = useDrop(() => ({ accept: 'YOUR_CUSTOM_ITEM_TYPE', drop: (item) => { // 这里的 item 就是拖拽源返回的对象 console.log('拿到拖拽内容:', item); }, collect: (monitor) => ({ isOver: monitor.isOver(), }), })); return <div ref={dropRef}>拖拽到这个区域试试</div>; }
2. 被 connectDropTarget 包裹的组件,如何在内部访问 this?
首先要明确:组件被connectDropTarget(高阶组件)包裹后,组件本身的this指向是完全正常的——你在组件的生命周期方法、自定义方法里,都能像普通类组件一样使用this.props、this.state或者this.setState()。
如果是想在**DropTarget的配置回调(比如drop、hover)**里访问组件实例的方法或状态,那可以用回调的第三个参数component——它就是当前组件的实例,直接通过它调用方法或者访问属性即可:
const dropTargetSpec = { drop(props, monitor, component) { // 通过 component 访问组件实例的状态与方法 component.setState({ draggedItem: monitor.getItem() }); component.handleDragComplete(); // 调用组件自定义的处理方法 } }; class MyDropComponent extends React.Component { state = { draggedItem: null }; // 用箭头函数自动绑定 this,避免指向问题 handleDragComplete = () => { console.log('拖拽完成,开始处理后续逻辑'); }; render() { // 这里的 this 完全正常,可直接访问 state 和 props return ( <div> {this.state.draggedItem ? `已拖拽内容:${this.state.draggedItem.name}` : '请拖拽内容到这里'} </div> ); } } // 最后用 DropTarget 高阶组件包裹组件 export default DropTarget( 'YOUR_CUSTOM_ITEM_TYPE', dropTargetSpec, connect => ({ connectDropTarget: connect.dropTarget() }) )(MyDropComponent);
要是你在组件内部(比如render或生命周期)发现this指向异常,大概率是自定义方法没有绑定this——用箭头函数定义方法,或者在constructor里手动绑定,和普通React类组件的处理方式一致就行~
内容的提问来源于stack exchange,提问作者qwe12345
相关产品推荐
相关产品推荐

