craft.js icon indicating copy to clipboard operation
craft.js copied to clipboard

useNode - dom is always 1 change behind the actual dom element

Open MarkLyck opened this issue 3 years ago • 2 comments

Describe the bug When getting dom from useNode. The dom element from the hook is always 1 iteration behind the actual element on the page.

To Reproduce Set up a useNode hook with dom & style in 1 component

const {
    style,
    dom,
  } = useNode((node) => ({
    dom: node.dom,
    style: node.data.props.style,
  }))

set up a setProp from useNode in a different component. and set the width to 100

The dom.offsetWidth will be 0

if you. then run setProp with style.width set to 200

The dom.offsetWidth will be 100

if you. then run setProp with style.width set to 50

The dom.offsetWidth will be 200

It's always 1 iteration behind the real deal.

This is incredibly frustrating trying to build an outline onRender component. as the size of my outline is always wrong, until a user hovers over the element.

Expected behavior I expect the dom element from useNode to be the actual element and have the same size/position as the element the user sees on the screen.

Screenshots If applicable, add screenshots to help explain your problem.

Initial size on first render is correct (width is set to 600 by default) Screen Shot 2021-03-12 at 09 29 52

using setProp I change the width to 400 Screen Shot 2021-03-12 at 09 30 54

Always 1 step behind the actual size :(

When I hover over the element, it fixes itself and corrects back to the right size.

The same problem can be observed in the landing page demo:

If you change the dimensions of something (from the side menu), the position of the "IndicatorDiv" is still at it's old height / position.

Screen Shot 2021-03-12 at 09 40 02

Until you hover the element and it updates.

MarkLyck avatar Mar 12 '21 14:03 MarkLyck

Not sure if it's the same underlying cause, but a similar issue exists when resizing the page - the menu doesn't follow the DOM it's attached to.

See the following as an example: Screen Shot 2022-11-03 at 2 15 55 pm

LouisSayers avatar Nov 03 '22 01:11 LouisSayers

I am experiencing an issue that is likely related. I have a User Component that maps a prop to render a list of components, i.e.

const MyUserComponent = ({ items }) => {
  return (
    <div>
      {items.map((item) => (
        <button>{item}</button>
      ))}
    </div>
  );
};

Initially, when the items prop is empty, the indicator shows up properly for my component.

Screenshot 2023-07-14 at 12 05 42 PM

However, when I add an item in the items prop, the dom value returned from useNode now seems to think the dom of my User Component is a <button /> instead of the parent <div />, as shown by the indicator in the screenshot below:

Screenshot 2023-07-14 at 12 09 13 PM

Not knowing the inner mechanics of craftjs, I have a hard time wrapping my head around why this is happening. To your observation @MarkLyck, I do see that even after deleting all items from the items prop, useNode still thinks the dom is the last existing <button /> although that doesn't even exist in the actual DOM any more.

vcheeze avatar Jul 14 '23 08:07 vcheeze