Let's suppose that you want to create a simple drag and drop list in React.
The first step is to define a list (fruits in this example 🍍), and render it as draggable
.
Then, define 3 functions: start()
, over()
and end()
:
jsximport React, { useState } from 'react'; const DragAndDrop = () => { const [list, setList] = useState(['Banana', 'Apple', 'Kiwi', 'Mango']); const [dragged, setDragged] = useState(null); const start = (e) => { /* Activates when user starts dragging */ } const over = (e) => { /* Activates while user is dragging */ } const end = () => { /* Activates when user finishes dragging */ } return( <div className = 'List'> {list.map((fruit, i) => <div key = {i} id = {i} onDragStart = {start} onDragEnd = {end} onDragOver = {over} draggable>{fruit}</div> )} </div> ); } export default DragAndDrop;
Save the id
of the component on drag start:
jsxconst start = (e) => { setDragged(e.target.id); }
Reset the variable on drag end:
jsxconst end = () => { setDragged(null); }
You'll need to move the fruit in the array of fruits and update the list accordingly while the user is dragging the element:
jsxconst over = (e) => { let newPosition = parseInt(e.target.id); if(newPosition >= 0){ let copy = [...list]; let moveFruit = ((from, to, fruit) => { copy.splice(from, 1); copy.splice(to, 0, fruit); })(dragged, newPosition, list[dragged]); setList(copy); setDragged(newPosition); } }
Important: notice how you need to setDragged(newPosition)
, as the fruit (dragged element) will change its position on the go.
Here is the final result:
jsximport React, { useState } from 'react'; const DragAndDrop = () => { const [list, setList] = useState(['Banana', 'Apple', 'Kiwi', 'Mango']); const [dragged, setDragged] = useState(null); const start = (e) => { setDragged(e.target.id); } const over = (e) => { let newPosition = parseInt(e.target.id); if(newPosition >= 0){ let copy = [...list]; let moveFruit = ((from, to, fruit) => { copy.splice(from, 1); copy.splice(to, 0, fruit); })(dragged, newPosition, list[dragged]); setList(copy); setDragged(newPosition); } } const end = () => { setDragged(null); } return( <div className = 'List'> {list.map((fruit, i) => <div key = {i} id = {i} onDragStart = {start} onDragEnd = {end} onDragOver = {over} draggable>{fruit}</div> )} </div> ); } export default DragAndDrop;
Hi, I'm Erik, an engineer from Barcelona. If you like the post or have any comments, say hi.