如何使用 react-draggable 将拖动的组件重置到其原始位置?



我尝试在我的应用程序中实现一个函数,允许用户重置他拖动的所有组件以重置到其原始位置。

我假设此功能存在于 react-draggable 中,因为这个关闭和发布的问题:"允许重置拖动位置"(https://github.com/idanen/react-draggable/issues/7(。但是我在文档(https://www.npmjs.com/package/react-draggable(中没有找到任何提示。

在stackoverflow中有一个内容相同的问题,但它已被删除(https://stackoverflow.com/questions/61593112/how-to-reset-to-default-position-react-draggable(。

感谢您的帮助:-(

GitHub 上引用的问题引用了一个提交。在查看了此提交中所做的更改后,我发现useDraggable钩子中添加了一个resetState回调。在提交的另一个地方,我发现了对测试文件的更改,该文件显示了钩子的用法。

function Consumer(props) {
const {
targetRef,
handleRef,
getTargetProps,
resetState,
delta,
dragging
} = useDraggable(props);
const { style = defaultStyle } = props;
return (
<main
className='container'
ref={targetRef}
data-testid='main'
style={style}
{...getTargetProps()}
>
{dragging && <span>Dragging to:</span>}
<output>
{delta.x}, {delta.y}
</output>
<button className='handle' ref={handleRef}>
handle
</button>
<button onClick={resetState}>reset</button>
</main>
);
}

钩子返回一组回调,包括此回调,可用于重置可拖动对象的状态。

我希望组件在删除组件时重置回其原始位置。

使用钩子,我监视组件是否被拖动,以及当它被错误重置位置时,否则它将未定义。

export default function DraggableComponent(props: any) {
const {label} = props
const [isDragging, setIsDragging] = useState<boolean>(false)
const handleStart = (event: any, info: DraggableData) => {
setIsDragging(true)
}
const handleStop = (event: any, info: DraggableData) => {
setIsDragging(false)
}
return (
<Draggable
onStart={handleStart}
onStop={handleStop}
position={!isDragging? { x: 0, y: 0 } : undefined}
>
<Item>
{label}
</Item>
</Draggable>
)
}

简单的方法是

  • 创建一个新组件以围绕可拖动回调包装我们的功能
  • 触发回调时onStop复位

例:

import { useState } from 'react';
import Draggable, { DraggableData, DraggableEvent, DraggableProps } from 'react-draggable';
export function Drag({ children, onStop, ...rest }: Partial<DraggableProps>) {

const initial = { x: 0, y: 0 }
const [pos, setPos] = useState(initial)
function _onStop(e: DraggableEvent, data: DraggableData){
setPos(initial)
onStop?.(e, data)
}

return (
<Draggable position={pos} onStop={_onStop} {...rest}>
{children}
</Draggable>
)
}

用法:

export function App() {
return (
<Drag> Drag me </Drag>
)
}

请注意,此答案不起作用。

这些方法都不适合我,但 tobi2424 关于 Draggable repo 问题 214 的帖子确实如此。下面是一个最小的概念验证:

import React from "react";
import Draggable from "react-draggable";
const DragComponent = () => {
// Updates the drag position parameter passed to Draggable
const [dragPosition, setDragPosition] = React.useState(null);
// Fires when the user stops dragging the element
const choiceHandler = () => {
setDragPosition({x: 0, y: 0});
};
return (
<Draggable
onStop={choiceHandler}
position={dragPosition}
>
Drag me
</Draggable>
);
};
export default DragComponent;

编辑

上面的代码间歇性地工作,但不是特别好。据我所知,react-draggable 将有关拖动元素位置的数据存储在 React 之外的某个位置,以便在组件刷新之间保留元素的位置。我无法确定如何在命令上重置元素的位置,并且没有其他示例代码可以为我解决问题。

你可以以一种非常随意的方式做到这一点。可能还有另一种方法可以更安全地设置状态,但我没有深入研究它。

import React from 'react';
export default class 😊 extends Component {
constructor(props) {
super(props);
this.draggableEntity = React.createRef();
}
resetDraggable() {
try {
this.draggableEntity.current.state.x = 0;
this.draggableEntity.current.state.y = 0;
} catch (err) {
// Fail silently
}

}

render() {
return (
<Draggable 
ref={this.draggableEntity}
>
<img onClick={(e) => {this.resetDraggable()}}></img>
</Draggable>
)
}
}

碰巧还有另一种方法!您可以使用它公开的ref元素来重置其偏移量。这可以像这样实现:

import React, {useRef, useCallback} from "react";
import Draggable from "react-draggable";
const DragComponent = () => {
// Updates the drag position parameter passed to Draggable
const [dragPosition, setDragPosition] = React.useState(null);
const draggerRef = useRef(null);
// Fires when the user stops dragging the element
const resetDrag = useCallback(() => {
setDragPosition({x: 0, y: 0});
draggerRef.current?.setState({ x: 0, y: 0 }); // This is what resets it!
}, [setDragPosition, draggerRef]);
return (
<Draggable
ref={draggerRef}
onStop={resetDrag}
position={dragPosition}
>
Drag me
</Draggable>
);
};
export default DragComponent;

我找到了这个问题的解决方案,而且很简单。

<Draggable
axis="both"
handle=".handle"
defaultPosition={{x: 0, y: 0}}
position={{x: 0, y: 0}}
scale={1}
}}>

你只需要设置position道具,所以onStop之后他会回到{x: 0, y: 0}

最新更新