[英]React ForwardRef: Property 'current' does not exist on type 'ForwardedRef<HTMLElement>'
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).问题是——实际的滚动容器不容易预测(在这种特定情况下,它既不是
window
、 document
也不是body
——它是div#__next
,由于 CSS 溢出规则)。
I want to keep the component flexible and self-contained.我想保持组件的灵活性和独立性。 So I've created a
ref
with DOM selector as an argument.所以我创建了一个带有 DOM 选择器的
ref
作为参数。 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 .
当前一个是 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:父组件没有红色波浪线(除非我通过
globalThis
,这似乎至少在 CodeSandbox 中有效),但是每当我访问current
属性时ScrollToTop
都会出现:
Property 'current' does not exist on type 'ForwardedRef<HTMLElement>'.
I've tried to use React.MutableRefObject<HTMLElement | null /* or other T's */>
我试过使用
React.MutableRefObject<HTMLElement | null /* or other T's */>
React.MutableRefObject<HTMLElement | null /* or other T's */>
, both in parent and in child, but it didn't help. React.MutableRefObject<HTMLElement | null /* or other T's */>
,无论是在父母身上还是在孩子身上,但它没有帮助。
Any ideas how to get the types to match?任何想法如何让类型匹配? Or is this a silly idea from the beginning?
或者这从一开始就是一个愚蠢的想法?
Refs might be objects with a .current
property, but they might also be functions. Refs可能是具有
.current
属性的对象,但它们也可能是函数。 So you can't assume that a forwarded ref has a .current
property.因此,您不能假设转发的 ref 具有
.current
属性。
I think it's a mistake to use forwardRef
at all here.我认为在这里使用
forwardRef
是一个错误。 The purpose of forwardRef
is to allow a parent component to get access to an element in a child component. forwardRef
的目的是允许父组件访问子组件中的元素。 But instead, the parent is the one finding the element, and then you're passing it to the child for it to use.但是相反,父元素是找到元素的人,然后您将其传递给子元素以供其使用。 I would use a regular state and prop for that:
我会使用常规的 state 和道具:
const Article = (props) => {
const [scrollContainer, setScrollContainer] = useState<HTMLElement | null>(() => {
return document.querySelector("#__next");
});
return (
<SomeContent>
<ScrollToTop treshold={640} scrollContainer={scrollContainer} />
</SomeContent>
)
interface ScrollToTopProps {
treshold: number;
scrollContainer: HTMLElement | null;
}
const ScrollToTop = ({ treshold, scrollContainer }: ScrollToTopProps) => {
const [visible, setVisible] = useState(false);
useEffect(() => {
if (scrollContainer) {
const toggle = throttle(toggleVisible, 300);
scrollContainer.addEventListener("scroll", toggle);
return () => {
scrollContainer.removeEventListener("scroll", toggle);
}
}
}, [scrollContainer]);
// ...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.