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

Add support for useRef #186

Closed
jantimon opened this issue Feb 26, 2019 · 5 comments
Closed

Add support for useRef #186

jantimon opened this issue Feb 26, 2019 · 5 comments

Comments

@jantimon
Copy link

Similar libraries allow to reuse a ref object for multiple hooks for example useComponentSize.
Those libraries use an official api from facebook: https://reactjs.org/docs/hooks-reference.html#useref

For your plugin usage might look like the following example:

const ref = useRef(null)
const [_, inView] = useInView({ref})
return <span ref={ref}>...</span>

One example for such an implementation is useComponentSize:

https://github.com/rehooks/component-size/blob/c0abcb9702f173cd5d52710af8604b29f2fbac17/index.js#L18

Could you please add this to your plugin?
My usecase is that I want to know the size of an component and if it is inviewport.

@thebuilder
Copy link
Owner

thebuilder commented Feb 28, 2019

This is a tricky issue. I originally made the Hook so you pass it a ref. This however had a few issues #162 #169 - Because the useRef doesn't trigger a change in useEffect, it would break if it wasn't set during the first render. The recommended solution is to use a ref callback, instead of the ref object.

See this blog post: https://medium.com/@teh_builder/ref-objects-inside-useeffect-hooks-eb7c15198780

I think you might be able to solve it by creating your own callback method.

const ref = useRef(null)
const [inViewRef, inView] = useInView()

function handleRef(node) {
  inViewRef(node);
  ref.current = node;
}

return <span ref={handleRef}>...</span>

(This is completely untested)

@thebuilder
Copy link
Owner

So i just tried this out, and it works fine - that'll be my recommended approach for this specific use case. Does it work for you?

function Component() {
  const [sizeRef, size] = useElementSize()
  const [inViewRef, inView] = useInView()

  function handleRef(node: HTMLElement | null) {
    sizeRef(node)
    inViewRef(node)
  }

  return <div ref={handleRef}>👋</div>
}

@kuworking
Copy link

It definitively works for me, thanks!

*The code here is clearer than the one in the readme, IMHO

@angelolucas
Copy link

angelolucas commented Oct 6, 2021

So i just tried this out, and it works fine - that'll be my recommended approach for this specific use case. Does it work for you?

function Component() {
  const [sizeRef, size] = useElementSize()
  const [inViewRef, inView] = useInView()

  function handleRef(node: HTMLElement | null) {
    sizeRef(node)
    inViewRef(node)
  }

  return <div ref={handleRef}>👋</div>
}

It looks like this logic creates an infinite loop. See here

@thebuilder
Copy link
Owner

See the FAQ section in the readme: https://github.com/thebuilder/react-intersection-observer#how-can-i-assign-multiple-refs-to-a-component

You'll need useCallback to ensure it memorizes the function.

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

No branches or pull requests

4 participants