ZeeCoder / use-resize-observer

A React hook that allows you to use a ResizeObserver to measure an element's size.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Externalise useResolvedElement

bpinto opened this issue Β· comments

Hi there, thanks for this great hook. Could you eventually release useResolvedElement as an external library? It would be good to reuse this without copying its function code.

Hey there! I appreciate that! πŸ™

It did cross my mind, but as small a task that may seem I think it won't happen in the near future, especially considering other higher-priority tasks.
The behavior of that hook is tested and ensured indirectly by the main hook's tests, which I'd have to replicate in the new package and then keep things in sync.

Honestly it's just not a complexity I'd be looking forward to with the very limited time I have all things considered. πŸ˜…

Where and how would you use it?

That's fair!

I have a couple hooks locally - some of them being replaced by useResizeObserver now that our list of supported browsers is getting bumped - that use similar techniques to work with callback refs or refs or state and the implementation is not as thorough as yours. Given the limited scope of useResolvedElement it feels like a great library to have and reuse.

Oh also, I believe useResolvedElement should use useLayoutEffect otherwise the calculation of the size will happen after the browser has painted the component causing it to flash from one position to another.

Can you elaborate on that a bit?
useResolvedElement is only resolving the html element to run RO with, it has nothing to do when or how size changes are reported? πŸ€”

@ZeeCoder I created a sandbox where the issue exists. When you click the button you should see a yellow box appearing and it should move right after being painted. Additionally if you see the console log, you should also see values 0 and 100 being printed.

The problem, I believe, is that useResolvedElement resolves the DOM element after the browser has painted it, not giving us the possibility to position an element before that happens.

ooh so it's really about the first observation, right at mount.
Makes sense, could be a patch release for sure.

I'm in Portugal on a company trip rn, but I'll try to take a look as soon as I can next week. πŸ‘

Thanks for the repro, efforts like these really make all the difference.

I'm in Portugal on a company trip rn, but I'll try to take a look as soon as I can next week. πŸ‘

What a coincidence. That's where I'm living now.

Thanks for the repro, efforts like these really make all the difference.

Thanks! I wanted to open a PR but I have no idea how to test this behavior. I tried googling for a little bit and was unsuccessful, I might see if react has any interesting test about this behavior.

Sorry, I'm not able to help you in that front, but I welcome recommendations! 😜

I was wondering if we could expose useResolvedElement from this package? Then you don't need a separate package, would be less useful for those only needing this hook since they would pull everything but it would at least allow others using this package to reuse useResolvedElement.

Yeah I thought of that but then I'd have increased the API surface, which now I'd have to maintain.
I want the freedom to be able to freely refactor or even remove this hook altogether from source if it made sense in the future, so I'd much rather make it a package of its own right.

I'm a bit torn here to be honest, while I did make this internal hook to resolve a ref easily whether it's a:

  • ref object passed through options,
  • an element, or
  • the ref callback being called,
    I don't actually want to spread the pattern.

If I were to start over, I would only allow for an element option, or a ref callback, but not for a ref object.

There are all sorts of complexities that come from handling it because there's no way to know if .current is still up to date or not, and it doesn't allow for lazy-mounting.

Not sure if I'm making sense, just sort of dumped my thoughts. πŸ˜…

I get that a ref object is convenient, especially if you have many hooks depending on an element, as then you can go:

create ref object
hook1
hook2
hook3

jsx

Basically just passing the object to each hook.
But you actually lose correctness, and increase the chance of unexpected behaviour.
I'd much rather promote the concept of merging refs instead and avoid a class of potential issues, making the package in turn lighter as well. πŸ€·β€β™‚οΈ

Not sure if that makes sense for you?