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

Add configurable debounce or throttling? #19

Closed bristoljon closed 4 years ago

bristoljon commented 5 years ago

I'm using this to size a user adjustable panel that contains a d3 graph so would be great if could debounce to prevent lot's of intermediate renders..

tj commented 5 years ago

👍 it seems to trigger on the same dimensions which seems a bit odd as well:

resize {width: 1097, height: 55}
resize {width: 1097, height: 55}
resize {width: 1097, height: 55}
resize {width: 1097, height: 55}
...
ZeeCoder commented 5 years ago

that's so weird @tj, how does that happen? browser version, etc? the lib is pretty much just forwarding values from the native implementation, but it's not hard to add throttle, debounce and actual change detection to avoid unnecessary renders.

tj commented 5 years ago

Yeah really strange haha, just using Chrome on a Mac. You're right thought, might as well delegate the debouncing part :D

Piero87 commented 5 years ago

I'm interested in this feature too, how can I achieve it? thanks!

ZeeCoder commented 4 years ago

I've created a simple example on how you can compose hooks to achieve debounce / throttle: https://codesandbox.io/s/use-resize-observer-throttle-and-debounce-example-8uvsg

☝ This is using a custom version of the hook which is really similar to the next major version. The most important change being that it memoises its response in order to avoid a cyclic render triggered by the debounced / throttled state changes.

I don't think debouncing and throttling are worth adding to this library. I'd prefer to use hook composition as shown above and keep the lib as simple and lean as possible.

The next major version will only report whole pixel sizes if they actually changed, as shown in this sandbox.

That said it's worth noting that even with all that being in place, rendering will be triggered in the host component on every size change even with a debounce or throttle in place, as the main hook is still setting state on every change, which is propegated whether or not the wrapping hook actually forwards these values or not.

Not sure how problematic that is or if there's a way to avoid a render coming from a hook nested like this, when its return values are not even used. 🤷‍♂️

ZeeCoder commented 4 years ago

This is now live with v5.