Search code examples
reactjs

Passing reference to DOM element down to component


I have some small utility component that has smooth scrolling:

const SmoothScroller = ({
    text,
    target,
}: {
    text: string
    target: HTMLElement | null
}) => {
    const scrollToTarget = () => {
        target?.scrollIntoView({
            behavior: 'smooth',
        })
    }

    return <a onClick={scrollToTarget}>{text}</a>
}

It requires however target element that needs to be scrolled into view.

So, the usage is to create reference to some DOM element and use it:

...
const ref = useRef<HTMLParagraphElement>(null)
...
return <>
<SmoothScroller
    target={ref.current}
    text="Scroll to paragraph"
/>
...
<p ref={ref} className="read-the-docs">
    Click on the Vite and React logos to learn more
</p>
</>

This however won't work, because ref.current can be null at time of render.

One solution would be to change

target: HTMLElement | null

to

target: () => HTMLElement | null

to pass function to get the element, but I think there's better solution to this.

So, how to correctly pass down such element reference?


Solution

  • Do not pass ref.current but ref itself. If you set a property on an object , any other code may see that property right away as long as it has access to the object. The object is ref, in this case. That way you may access up-to-date DOM element whenever you need it. That is what useRef is for.