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

[useMeasure] Ability to track a custom Ref #1227

Open
ashubham opened this issue May 18, 2020 · 15 comments
Open

[useMeasure] Ability to track a custom Ref #1227

ashubham opened this issue May 18, 2020 · 15 comments
Labels
good first issue Good for newcomers help wanted Extra attention is needed

Comments

@ashubham
Copy link

ashubham commented May 18, 2020

Is your feature request related to a problem? Please describe.

Currently useMeasure returns a ref which needs to be assigned a ref in the JSX.
This has 2 issues:

  1. The ref is not a real useRef for eg. Does not have ref.current as a prop.
  2. If I already have a component where I have a ref, I just want to track its size changes.

Describe the solution you'd like

An API of this shape:
const {width, height ... } = useMeasure({ref: currentRef});

Describe alternatives you've considered

I am using https://github.com/ZeeCoder/use-resize-observer ... in the absence of the above which I want to remove.

@michelecocuccio
Copy link

michelecocuccio commented May 19, 2020

+1 on this. I already have my ref so it will be useful to pass a ref as an argument. This will also give the ability to use more than one useMeasure in the same component, as I need to track three different elements.

@evadecker
Copy link

I just ran in the same issue, would also love this!

@streamich streamich added good first issue Good for newcomers help wanted Extra attention is needed labels Jun 7, 2020
@dmitrij-borchuk
Copy link

Hey! How do you think, should we pass a real ref there or just an element?

const {width, height ... } = useMeasure({ ref: ref });

or

const {width, height ... } = useMeasure({ element: ref.current });

I am asking because ref is not used inside so we don't need it.

@dmitrij-borchuk
Copy link

Looks like this proposal contains breaking backward compatibility. Should new PR implement it like that?
Currently, it returns an array where the first element is ref, but with passing ref as an argument, we don't need this returning ref. In case we need to save backward compatibility the interface will be strange:

const rect = useMeasure({ ref: elementRef })[1];

or

const { '1': stateArgs } = useMeasure({ ref: elementRef });

@dmitrij-borchuk
Copy link

@ashubham @streamich What do you think?

@joeshub
Copy link

joeshub commented Jun 17, 2020

what if you create and return a ref if no ref was passed in?

@dmitrij-borchuk
Copy link

@joeshub Great idea for the JavaScript but how TypeScript types should look like in this case?

@priley86
Copy link

priley86 commented Sep 7, 2020

+1 for supporting a passed ref

@PoOw
Copy link

PoOw commented Sep 15, 2020

@joeshub Great idea for the JavaScript but how TypeScript types should look like in this case?

Could be something like that ?

<E extends HTMLElement = HTMLElement>(element?: E): UseMeasureResult<E>

If the element parameter is passed, you use it to initiate the element state in the hook. This way, there is no breaking change.

You could use the hook like that :

const [, { width, height,... }] = useMeasure(element);

Looks like this proposal contains breaking backward compatibility. Should new PR implement it like that?
Currently, it returns an array where the first element is ref, but with passing ref as an argument, we don't need this returning ref. In case we need to save backward compatibility the interface will be strange.

@dmitrij-borchuk Another solution could be to have two distinct types for the hook :

{
  <E extends HTMLElement = HTMLElement>(): UseMeasureResult<E>;
  <E extends HTMLElement = HTMLElement>(element: E): UseMeasureRect;
}

This would keep backward compatibility, without having a too weird interface. But this will add more complexity in the code, so I'm not sure it's worth it. What do you think ?

@dmitrij-borchuk
Copy link

@PoOw Thank you for the idea, you are awesome! I totally forget that TypeScript has Overloads (https://www.typescriptlang.org/docs/handbook/functions.html#overloads). I will work around that solution

@saiichihashimoto
Copy link

@dzcpy
Copy link

dzcpy commented Mar 15, 2021

+1
Or, an alternative way would be exposing useMeasureDirty.
Currently I can only import it like this:
import useMeasureDirty from 'react-use/lib/useMeasureDirty';
But it works well. It takes a real ref as and argument and then returns the dimension. Not sure why it's not in the export list

@JoeDuncko
Copy link

JoeDuncko commented Sep 2, 2021

Hi all! @react-hookz/web, the new library by one of react-use's former maintainers (background here and here) has a new implementation of useMeasure that solves point (1) of this issue, which might make point (2) moot for most users.

For those interested, there's an official migration guide for migrating from react-use to @react-hookz/web.

Hope this helps!

@terragady
Copy link

is there any update on this? Passing ref from useMeasure as a ref gives typescript error as it is not a accepted ref object:
(property) ref?: ((instance: HTMLDivElement | null) => void) | React.RefObject<HTMLDivElement> | null | undefined

@JoeDuncko
Copy link

is there any update on this? Passing ref from useMeasure as a ref gives typescript error as it is not a accepted ref object: (property) ref?: ((instance: HTMLDivElement | null) => void) | React.RefObject<HTMLDivElement> | null | undefined

Hi @terragady , react-use is effectively no longer maintained.

@react-hookz/web, the new library by one of react-use's former maintainers (background here and here) has a new implementation of useMeasure that solves point (1) of this issue, which might make point (2) moot for most users.

Hope that helps!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests