Last active
August 30, 2020 15:41
-
-
Save YuCJ/bfd8e16eae07f55fe6cc3cee70e13ad3 to your computer and use it in GitHub Desktop.
In React, we use `ref` to touch the DOM element directly. When a component takes refs passed by its parent, and it needs to touch the DOM element by itself also, we have to compose the refs into one so we can pass it to the child..
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function updateElementInRef(element, ref) { | |
if (typeof ref === 'function') { | |
/* | |
The ref is a callback ref. | |
https://reactjs.org/docs/refs-and-the-dom.html#callback-refs | |
*/ | |
ref(element) | |
} else if (ref) { | |
/* | |
The ref is an object expected to be mutated with property `current`. | |
It's the returned object of React.useRef() hook (interface React.MutableRefObject) | |
or the returned object of React.createRef() (interface React.RefObject). | |
*/ | |
ref.current = element | |
} else { | |
/* Not a valid ref. Handle the exceptions here */ | |
} | |
} | |
export default function composeRefs(...refs) { | |
return function composedRef(element) { | |
const refCount = refs.length | |
for (let i = 0; i < refCount; i += 1) { | |
const ref = refs[i] | |
updateElementInRef(element, ref) | |
} | |
} | |
} | |
/* USAGE EXAMPLE */ | |
const ForwardRefVideo = React.forwardRef((props, upperRef) => { | |
const videoEleRef = React.useRef(null) | |
const composedRef = composeRefs(videoEleRef, upperRef) | |
/* `videoEleRef.current` will be the video DOM element */ | |
return ( | |
<video ref={composedRef}> | |
{props.sources.map((source, i) => ( | |
<source key={`${i}-source`} src={source.src} type={source.type} /> | |
))} | |
<p>This browser does not support the video element.</p> | |
</video> | |
) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment