react-native-draggable icon indicating copy to clipboard operation
react-native-draggable copied to clipboard

Saving new positions to state after drag

Open ugrdursun opened this issue 3 years ago • 10 comments

Hello, firstly thanks for this beautiful library

I couldnt figure out how to get new positions of draggable after drag or while dragging to save state. I use latest version.

  state={
    elements: [
      {
        id:'somenode1',
        type:'node',
        position_x: 190,
        position_y: 150,
        node_width: 160,
        node_height: 60,
        data: {
          title:'CHILD1'
        }
      },

...
      <>
      <View style={{backgroundColor:'#bbe1fa', borderTopColor:'#b8b5ff', height:SCREEN_HEIGHT, width:SCREEN_WIDTH, flex:1}}>

                {this.state.elements.map((item, key) =>  {


                          return (

                            <Draggable

                          onDragRelease={(e,g,b) => {

                            this.dragNode(item, g.moveX, g.moveY)


                          } }
                          x={item.position_x}
                          y={item.position_y}
                          z={1000}

......
  dragNode = (node, newX, newY) => {

    var elements = this.state.elements

           var newNode = node

            //REMOVE THE NODE
            var newElements = elements.filter(item2 => item2.id != node.id)

            //EDIT POSITIONS
            newNode.position_x = newX
            newNode.position_y = newY
    
            //PUSH NEW ONE
            console.log(newNode)
            newElements.push(newNode)
    
            //SET AS STATE
            this.setState({elements:newElements})

  }

Its not working properly this way, going crazy and draggable places some irrevelant places

I think as you know better the problem is g.moveX is returning touch positions. But i want to get latest position of draggable after drag. Draggable works smooth, I just want to pass latest positions to state to store them.

Thanks for your support

ugrdursun avatar Apr 08 '21 08:04 ugrdursun

Thanks for workaround

garrylachman avatar Apr 10 '21 21:04 garrylachman

Thanks for workaround

Its not actually a "workaround". nodes going crazy after release

ugrdursun avatar Apr 12 '21 06:04 ugrdursun

So you remove and re-add them... this is classic workaround for a problem. its not direct solution that fixed the problem why they go crazy - its a workaround to "bypass" the issue

garrylachman avatar Apr 12 '21 06:04 garrylachman

Same problem here, I tried everything with no success and pageX and locationx is sooo confusing :( Did you managed to do it? @baconcheese113 @tongyy Do you know how can we achive that? I need help :(

LiLPandemio avatar May 03 '21 06:05 LiLPandemio

Same problem here, I tried everything with no success and pageX and locationx is sooo confusing :( Did you managed to do it? @baconcheese113 @tongyy Do you know how can we achive that? I need help :(

Still could not find the solution. Library smoothly dragging item to wherever we want but X Y outputs are not matching with wrappers X Y

ugrdursun avatar May 31 '21 09:05 ugrdursun

Hello,

From my experience with this library, it appears that there are some internal X/Y stored values in it (offsets ?) that are not reinitialized when passing new X/Y props.

It may result in having the draggable going to crazy places after releasing the drag.

The only solution i found is similar to your workaround :

  • add a "key" prop based of the value you pass on X and Y in the Draggable component.
  • this will force to destroy and recreate the component based on the new X and Y values.

Hope that this will help someone as i've been stucked for a while on this !

paul-leymet avatar Jun 23 '21 09:06 paul-leymet

Hello,

From my experience with this library, it appears that there are some internal X/Y stored values in it (offsets ?) that are not reinitialized when passing new X/Y props.

It may result in having the draggable going to crazy places after releasing the drag.

The only solution i found is similar to your workaround :

  • add a "key" prop based of the value you pass on X and Y in the Draggable component.
  • this will force to destroy and recreate the component based on the new X and Y values.

Hope that this will help someone as i've been stucked for a while on this !

Thanks for idea. I am currently trying to solve this issue right now.

onDragRelease={(event, gestureState, bounds) => { console.log(bounds.top , bounds.left)

Actually bounds prop working more stable than gestureState due I think its returning current position inside wrapper. But this one also changing position some X Y position after saving to state. Also its bad bounds is not a prop of onDrag :(

ugrdursun avatar Jun 23 '21 13:06 ugrdursun

Did you find any solutions? I'm having the same problem. Dragging works fine but trying to save the positions on onDragRelease makes the image jump.

Audeos avatar Aug 03 '21 14:08 Audeos

I'm also running into this problem.

KolbySisk avatar Aug 09 '21 03:08 KolbySisk

Hello,

From my experience with this library, it appears that there are some internal X/Y stored values in it (offsets ?) that are not reinitialized when passing new X/Y props.

It may result in having the draggable going to crazy places after releasing the drag.

The only solution i found is similar to your workaround :

  • add a "key" prop based of the value you pass on X and Y in the Draggable component.
  • this will force to destroy and recreate the component based on the new X and Y values.

Hope that this will help someone as i've been stucked for a while on this !

Thanks for the workaround! As Paul says, just add to your Draggable a key prop and pass to it a value that changes every time you complete the action. You can use also x,y unless you are moving perfectly on of those directions. Alternatively you can use Date.now()

Create first a state to hold this value which trigger the re-render of the entire Draggable. const [reloader, setReloader] = React.useState<number>(Date.now());

Add the value as a key to your draggable. <Draggable key={reloader} />

Set the state every time you want the entire object to be re-rendered, for example inside the function that you call in onDragRelease setReloader(Date.now());

Just remember that this still a workaround and it might not be the best way to go :)

matteosprintdigital avatar Aug 11 '21 07:08 matteosprintdigital