Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Storing and Rendering State Instead of Direct DOM Manipulation Breaks in React 18 #1119

Open
SebastianBaltes opened this issue Jun 11, 2024 · 0 comments

Comments

@SebastianBaltes
Copy link

Environments

Description

In my use case, I need to store the coordinates, size, and rotation of the target as React state and use that state to render the target instead of manipulating the DOM directly. In React 17, the following code snippet worked:

react 17 sandbox

  const targetRef = useRef<HTMLDivElement>(null);
  const [offset, setOffset] = useState({ x: 0, y: 0 });
  const [coords, setCoords] = useState({ x: 100, y: 50, w: 100, h: 100 });
  console.log(coords);
  return (
    <>
      <div
        ref={targetRef}
        className="target resizable"
        style={{
          left: coords.x + "px",
          top: coords.y + "px",
          width: coords.w + "px",
          height: coords.h + "px",
        }}
      >
        Target
      </div>
      <Moveable
        target={targetRef}
        draggable={true}
        resizable={true}
        onDragStart={() => {
          const { x, y } = coords;
          setOffset({ x, y });
        }}
        onResizeStart={() => {
          const { x, y } = coords;
          setOffset({ x, y });
        }}
        onDrag={({ translate }) => {
          const [x, y] = translate;
          setCoords({
            ...coords,
            x: x + offset.x,
            y: y + offset.y,
          });
        }}
        onResize={({ transform, width, height }) => {
          const [x, y] = transform
            .slice(transform.indexOf("(") + 1, transform.indexOf(")"))
            .split(",")
            .map((e) => parseFloat(e.trim().split("px")[0]));
          setCoords({
            x: x + offset.x,
            y: y + offset.y,
            w: width,
            h: height,
          });
        }}
      />
    </>
  );

However, with React 18, the same code does not work as expected:

react 18 sandbox

When resizing by dragging the top left handle, the coordinates diverge. The moveable component and the target split positions.

This may not be the correct way to use your library. How can I implement this use case correctly? It's important for me to manage the state and not use direct transformations because, under the hood, it's a Three.js object rendered on a 2D stage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
1 participant