Moveable: Cant get basic version working in React?

Created on 25 Oct 2019  路  6Comments  路  Source: daybrush/moveable

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;

React question

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

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}
    />
  );
};

All 6 comments

@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
Was this page helpful?
0 / 5 - 0 ratings

Related issues

MiiZZo picture MiiZZo  路  3Comments

monsterooo picture monsterooo  路  4Comments

copthuy picture copthuy  路  4Comments

tesmem101 picture tesmem101  路  3Comments

masoudelahi picture masoudelahi  路  5Comments