Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing a basic drag functionality in ReactJS

Based on the create-react-app template, I'm trying to implement a very basic drag / drop scenario. My App.js currently looks like this:

import React, { Component } from 'react';
import './App.css';

class App extends Component {
  render() {
    const myStyle = {
      height: '100px',
      width: '200px',
      top: '50px',
      left: '100px',
      position: 'absolute',
      borderStyle: 'solid',
      borderColor: 'blue',      
    };

    return (

      <div className="App">        
          <div style={myStyle} draggable>test</div>
          <div>test2</div>        
      </div>
    );
  }
}

export default App;

My question is that, from all the tutorials and documentation that I've seen, I understood the addition of the draggable property to cause the element to be draggable, however, it is not.

What additional properties need to be set to make an object draggable? (I'm not interested in dropping anything at this stage.)


1 Answers

This can be a core implementation of the drag behaviour in React. It needs enhancements of course, plus does not handle dropping yet:

const { useRef } = React

const App = () => {
  const elemRef = useRef(null)
  const dragProps = useRef()
  
  const initialiseDrag = event => {
    const { target, clientX, clientY } = event
    const { offsetTop, offsetLeft } = target
    const { left, top } = elemRef.current.getBoundingClientRect()
    
    dragProps.current = {
      dragStartLeft: left - offsetLeft,
      dragStartTop: top - offsetTop,
      dragStartX: clientX,
      dragStartY: clientY
    }
    window.addEventListener('mousemove', startDragging, false)
    window.addEventListener('mouseup', stopDragging, false)
  }
  
  
  const startDragging = ({ clientX, clientY }) => {    
    elemRef.current.style.transform = `translate(${dragProps.current.dragStartLeft + clientX - dragProps.current.dragStartX}px, ${dragProps.current.dragStartTop + clientY - dragProps.current.dragStartY}px)`
  } 

  const stopDragging = () => {
    window.removeEventListener('mousemove', startDragging, false)
    window.removeEventListener('mouseup', stopDragging, false)
  }
  
  return (
    <div
      onMouseDown={initialiseDrag}
      ref={elemRef}
      >
      DragMe
    </div>
  )
}

ReactDOM.render(<App />, document.getElementById('root'));
div {
  cursor: grab;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>
like image 101
gazdagergo Avatar answered Feb 26 '26 03:02

gazdagergo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!