I'm not sure if Im missing something basic but the following does nothing. I would expect something to get logged to the console when I tried to drag?
import React from "react";
import Moveable from "react-moveable";
class SomeComponent extends React.Component {
render() {
return (
<React.Fragment>
<div className="draggable">
<div>Drag me</div>
</div>
<Moveable
target={document.querySelector(".draggable")}
draggable={true}
throttleDrag={0}
onDragStart={res => {
console.log(res);
}}
onDrag={res => {
console.log(res);
}}
/>
</React.Fragment>
);
}
}
export default SomeComponent;
@jameschetwood
First the document.querySelector (".dragable") is null before it is mounted.
I've tried only rendering the component that contains Moveable after a toggle button is clicked so I know that div.draggable will be in the DOM.
const Parent = () => {
const [show, setShow] = React.useState(false);
return (
<div>
<button onClick={() => setShow(!show)}>Toggle Show</button>
<div className="draggable">Drag me</div>
{show && <SomeComponent />}
</div>
)
}
However now I get an error. Im using TypeScript:
Uncaught TypeError: Cannot read property 'getElement' of undefined
Should I use a ref? I couldn't see that in the docs but that would be more idiomatic for React I think?
@jameschetwood
react-moveable 0.12.12 is released. Try it again.
Thank you :)
Working, thanks!
Quickly reopening just so I can share some code of this working incase it helps someone else finding this issue. Here is the codepen link: https://codesandbox.io/s/recursing-archimedes-jzw6p
function App() {
return (
<div className="App">
<ThingToMove />
</div>
);
}
const ThingToMove = () => {
const moveRef = React.useRef(null);
const [style, setStyle] = React.useState("");
return (
<div>
<h2
ref={moveRef}
style={{
transform: style
}}
>
Move me
</h2>
<MovableComponent moveRef={moveRef} setStyle={setStyle} />
</div>
);
};
const Movable = ({ moveRef, setStyle }) => {
const [renderMovable, settRenderMovable] = React.useState(false);
React.useEffect(() => {
settRenderMovable(true);
}, []);
const handleDrag = e => {
setStyle(e.transform);
};
if (!renderMovable) return null;
return (
<Moveable
target={moveRef.current}
draggable={true}
throttleDrag={0}
onDrag={handleDrag}
/>
);
};
@jameschetwood thank you! None of the examples on the repo are actually helpful.
Yours works with 1 modification:
const Movable = ({ moveRef, setStyle }) => {
should be
const MovableComponent = ({ moveRef, setStyle }) => {
Here is a full working example that can be pasted into App.js of a new react-create-app app:
import React from "react";
import Moveable from "react-moveable";
function App() {
return (
<div className="App">
<ThingToMove />
</div>
);
}
const ThingToMove = () => {
const moveRef = React.useRef(null);
const [style, setStyle] = React.useState("");
return (
<div>
<h2
ref={moveRef}
style={{
transform: style
}}
>
Move me
</h2>
<MovableComponent moveRef={moveRef} setStyle={setStyle} />
</div>
);
};
const MovableComponent = ({ moveRef, setStyle }) => {
const [renderMovable, settRenderMovable] = React.useState(false);
React.useEffect(() => {
settRenderMovable(true);
}, []);
const handleDrag = e => {
setStyle(e.transform);
};
if (!renderMovable) return null;
return (
<Moveable
target={moveRef.current}
draggable={true}
throttleDrag={0}
onDrag={handleDrag}
/>
);
};
export default App
Most helpful comment
Quickly reopening just so I can share some code of this working incase it helps someone else finding this issue. Here is the codepen link: https://codesandbox.io/s/recursing-archimedes-jzw6p