daybrush / moveable

Moveable! Draggable! Resizable! Scalable! Rotatable! Warpable! Pinchable! Groupable! Snappable!
https://daybrush.com/moveable/
MIT License
10.08k stars 618 forks source link

Immediately after `setState` target, the `moveable.target` is still not updated directly #568

Closed chenxeed closed 2 years ago

chenxeed commented 2 years ago

Environments

Description

I need to handle the scenario when the user mousedown the targeted element, it can immediately be dragged.

To do it, I need to run this kind of code on mousedown the element:

target.addEventListener("mousedown", (e) => {
  moveable.setState({
    target: [target]
  });
  moveable.dragStart(e);
});

It was working before, until recently I realized after upgrade to the latest package, it doesn't work anymore. The reason seems like because right after moveable.setState({ target: targetElem }), it doesn't immediately set the moveable.target.

I created the codesandbox to replicate the issue. This is the screenshot:

chenxeed commented 2 years ago

From my investigation, it might have something to do with react-simple-compat changes here:

https://github.com/daybrush/react-simple-compat/commit/3f86e298f204e588a1788f5366505a3c22aeb13d#diff-b2783ac79ef1f4fda3bafed7f7dc8020aad205ad05efbc770e8ff04aa344ba68R528-R535

It makes the state changes become asynchronous, thus the target is not immediately updated.

daybrush commented 2 years ago

@chenxeed

Try it like the code below:

  moveable.setState({
    target: [target]
  }, () => {
    moveable.dragStart(e);
  });
chenxeed commented 2 years ago

I can do that, however in my code logic, the code that set the moveable target state and the one to immediate dragstart is different, thus I can't really set a callback for that.

I saw that in the setState from react-simple-compat, it has 3rd parameter isForceUpdate to update the state synchronously.

https://github.com/daybrush/react-simple-compat/blob/master/src/Compat.tsx#L520

However the 3rd param is not accessible through the moveable.setState. I wonder if it's intended, or we can improve the moveable.setState to also accept the 3rd param for isForceUpdate.

daybrush commented 2 years ago

@chenxeed

setState is asynchronous and forceUpdate is a synchronous method.

I will add a forceUpdate method to the moveable.

daybrush commented 2 years ago

@chenxeed

moveable's new version is released. and forceUpdate method is added. Check it again.