ZeeCoder / use-resize-observer

A React hook that allows you to use a ResizeObserver to measure an element's size.
MIT License
651 stars 42 forks source link

Rounded widths and heights #61

Closed DrewVartanian closed 3 years ago

DrewVartanian commented 3 years ago

Would it be possible to use getBoundingClientRect() to measure widths and heights, so that the values are not rounded? I have run into situations where not having the floating-point values has caused issues when using those measurements. If there is a situation where users may want the rounded value that I am not thinking of, then having an option to get the floating-point values would also work.

ZeeCoder commented 3 years ago

There's something in the works for this, I'm just way to strained to take a proper look. :(

See also: https://github.com/ZeeCoder/use-resize-observer/issues/46#issuecomment-735247624

We're not using getBoundingClientRect as one of the big selling points to using uRO is it not triggering a layout in the browser like getBoundingClientRect does.

DrewVartanian commented 3 years ago

@ZeeCoder Don't worry at all about not being able to get to this. You are in no way obligated to do anything here, and I appreciate you taking the time to respond in the first place.

Just for posterity's sake, I'm going to include my current work around, in case it helps eventually solve this issue, or provides help to anyone else who is facing it. I am currently getting a width from the useResizeObserver, and use that width as a dependent in my useEffect hook, where I am reacting to the change. In that useEffect hook, after checking to make sure the ref provided too useResizeObserver has an element at current, I get the non rounded width with ref.current.getBoundingClientRect().width. This means that my component will react to changes in the rounded width, and use the floating-point width for my calculations. While this obviously is not perfect, as it will not respond to width changes that are small enough that don't change the rounded width, for my use case it is more than good enough.

Two last caveat to leave behind for other people to consider, and possible explain if they understand better. First, I do not completely understand the issue of "uRO is it not triggering a layout in the browser like getBoundingClientRect does", and thus any issues that come out of that fact are not taking into consideration in my solution above. Second, an alternative too using getBoundingClientRect seems to be getComputedStyle, as in parseFloat(window.getComputedStyle(ref.current).width). This also provides a floating-point value for the width, although the number is slightly different from that obtained by getBoundingClientRect. As for the cause of the difference, and any other differentiating aspect of the two methods, I don't have good enough understanding to offer an explanation. That said, hopefully this helps anyone who is facing this issue or looking to create a PR on this library, as a point of reference.

ZeeCoder commented 3 years ago

@DrewVartanian really appreciate you taking the time to write all that feedback. :ok_hand: If you're interested, a good starting point to learn about the performance issues about "layout trashing" could be this.

github-actions[bot] commented 3 years ago

:tada: This issue has been resolved in version 8.0.0 :tada:

The release is available on:

Your semantic-release bot :package::rocket: