I am trying to create a component that will track the vertical scroll. The catch is – the actual scroll container is not easily predictable (in this specific case it is neither window
, document
nor body
– it is div#__next
, due to CSS overflow rules).
I want to keep the component flexible and self-contained. So I've created a ref
with DOM selector as an argument. I know it is far from idiomatic (to say the least), but it suprisingly seems to be working:
// Parent component
import { useRef } from "react"
const Article = (props) => {
const scrollContainerRef = useRef<HTMLElement | null>(
document.querySelector("#__next") // <-- the scroll container reference
)
return (
<SomeContent>
<ScrollToTop treshold={640} ref={scrollContainerRef} />
</SomeContent>
)
// ScrollToTop
const ScrollToTop = forwardRef(
({ treshold }, ref) => {
const [visible, setVisible] = useState(false)
useEffect(() => {
if (ref?.current) {
ref.current.addEventListener("scroll", throttle(toggleVisible, 300))
return () => {
ref.current.removeEventListener("scroll", throttle(toggleVisible, 300))
}
}
}, [])
// …
So what's the problem? the current one is Typescript. I've spent hours trying to get the types right, but to no avail. The parent component is red squigly lines free (unless I pass globalThis
, which seems to work at least in CodeSandbox), but the ScrollToTop
is compaining whenever I am accessing current
property:
Property 'current' does not exist on type 'ForwardedRef<HTMLElement>'.
I've tried to use React.MutableRefObject<HTMLElement | null /* or other T's */>
, both in parent and in child, but it didn't help.
Any ideas how to get the types to match? Or is this a silly idea from the beginning?
scrollContainerRef
is shown to beReact.MutableRefObject<HTMLElement>
when hovering over. But if I try to use that in the child component, I got errors. – Saransarangi