React DnD - element transform (rotate) applied before dragging is not displayed immediately, but after drop

64 Views Asked by At

I want to implement a simple drag-and-drop GUI with React DnD where elements can be rotated as well. As a starting point, I adapted this example from the React DnD website.

My problem is that the rotation which is applied via a button (+90 degrees per button click) to the previously selected (clicked) box is not displayed immediately, but only after the box is dragged and dropped again.

My fork with my changes can be found and run in this codesandbox.

The flow starts in the Container.tsx file, where I set the rotation property of the box structure to the desired target rotation (after the button has been clicked):

const rotateSelectedBox = () => {
  if (selectedBoxId != undefined) {
    boxes[selectedBoxId].rotation =
      (boxes[selectedBoxId].rotation + 90) % 360;
  }
};

The rotation is then piped through some components until it is supposed to be displayed by setting the according CSS property (transform, WebkitTransform) in the styles attribute of the box (Box.tsx)

style={{
  ...styles,
  backgroundColor,
  transform: `rotate(${rotation}deg)`,
  WebkitTransform: `rotate(${rotation}deg)`,
}}

I think the data goes through the components in this order:

Container --> DraggableBox --> (via useDrag) --> CustomDragLayer --> BoxDragPreview --> Box

but also in this order:

Container --> DraggableBox --> (via component return) --> Box

return (
  <div
    ref={drag}
    style={getStyles(left, top, isDragging)}
    role="DraggableBox"
    onClick={handleClick}
  >
    <Box title={title} rotation={rotation} />
  </div>
);

Apparently, the changed rotation value reaches the Box component only after the box has been dragged and dropped again. But I don't know why. I expected it to reach the Box component directly since the DraggableBox component returns the rotation as well. I want the applied rotation to be displayed immediately and during the dragging the correct rotation should also be displayed.

0

There are 0 best solutions below