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

Externalise useResolvedElement #101

Open
bpinto opened this issue Feb 16, 2023 · 11 comments
Open

Externalise useResolvedElement #101

bpinto opened this issue Feb 16, 2023 · 11 comments
Labels
enhancement New feature or request

Comments

@bpinto
Copy link

bpinto commented Feb 16, 2023

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.

@ZeeCoder
Copy link
Owner

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?

@ZeeCoder ZeeCoder added the enhancement New feature or request label Feb 16, 2023
@bpinto
Copy link
Author

bpinto commented Feb 17, 2023

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.

@bpinto
Copy link
Author

bpinto commented Feb 17, 2023

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.

@ZeeCoder
Copy link
Owner

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? 🤔

@bpinto
Copy link
Author

bpinto commented Feb 20, 2023

@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.

@ZeeCoder
Copy link
Owner

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.

@bpinto
Copy link
Author

bpinto commented Feb 20, 2023

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.

@ZeeCoder
Copy link
Owner

ZeeCoder commented Feb 20, 2023 via email

@bpinto
Copy link
Author

bpinto commented Feb 22, 2023

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

@bpinto
Copy link
Author

bpinto commented Feb 23, 2023

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.

@ZeeCoder
Copy link
Owner

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants