How to merge refs in React component?
If you’ve used React, you’ll be familiar with ref. It is easier to use, but you would need multiple refs to be attached to the component for certain use cases. In that situation, you might probably use a library. What if I tell you that you can write mergeRefs function in maximum 10 lines. Let’s go step by step.
import React from "react"
export default () => {
const ref = React.useRef(null)
return <div ref={ref}>Hello</div>
}
If props are function, They will communicate through parameters in outside world. For instance in onChange
or onClick
or any DOM event on elements, we will get the event
from function parameter. onChange={(event) => console.log(event)}
. Let’s try it on ref
to see what it provides.
import React from "react"
export default () => {
const ref = (...args) => console.log(args)
return <div ref={ref}>Hello</div>
}
You’ll get something like this in console
.
[div]
If you expand that array, you’ll get to know that it is nothing but DOM Element, which is same that we access in refs by someRef.current
. We now also know that ref
props function provides single parameter. Though these details can be accessed by typescript as well.
With all that knowledge, assume we want to merge only two refs. We can do it this way.
import React from "react"export default () => {
const ref1 = React.useRef(null)
const ref2 = React.useRef(null) return (
<div
ref={node => {
ref1.current = node
ref2.current = node
}}
>
Hello
</div>
)
}
Since, ref1
and ref2
are readonly but ref1.current
and ref2.current
are mutable object, we can modify their value.
We can generalise this approach in mergeRef
function which would look like this
const mergeRefs = (...refs) => {
return node => {
for (const ref of refs) {
ref.current = node
}
}
}
It could be utilised by providing it to ref
prop.
import React from "react"const mergeRefs = (...refs) => {
return node => {
for (const ref of refs) {
ref.current = node
}
}
}export default () => {
const ref1 = React.useRef(null)
const ref2 = React.useRef(null) return <div ref={mergeRefs(ref1, ref2)}>Hello</div>
}
I hope basic is clear; now you can modify mergeRefs
function according to your requirements.
Thanks for reading.