简体   繁体   English

React ForwardRef:“ForwardedRef”类型上不存在属性“current”<htmlelement> '</htmlelement>

[英]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).问题是——实际的滚动容器不容易预测(在这种特定情况下,它既不是windowdocument也不是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?或者这从一开始就是一个愚蠢的想法?

CodeSandbox demo CodeSandbox 演示

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.

相关问题 React forwardRef - 类型 IntrinsicAttributes 上不存在属性 - React forwardRef - Property does not exist on type IntrinsicAttributes React TypeScript 和 ForwardRef - 类型“IntrinsicAttributes”上不存在属性“ref” - React TypeScript & ForwardRef - Property 'ref' does not exist on type 'IntrinsicAttributes useRef Typescript 错误:“HTMLElement”类型上不存在属性“current” - useRef Typescript error: Property 'current' does not exist on type 'HTMLElement' TypeScript 类型“HTMLElement”上不存在属性“值”。 反应笑话测试 - TypeScript Property 'value' does not exist on type 'HTMLElement'. React Jest Testing React 测试库-“HTMLElement”类型上不存在属性“值” - React testing library - Property 'value' does not exist on type 'HTMLElement' React 测试库中的“HTMLElement”类型不存在属性“值” - Property 'value' does not exist on type 'HTMLElement' in React Testing Library “匹配器”类型上不存在属性“toBeInTheDocument”<htmlelement> '</htmlelement> - Property 'toBeInTheDocument' does not exist on type 'Matchers<HTMLElement>' “HTMLElement”类型上不存在属性“src” - Property 'src' does not exist on type 'HTMLElement' 类型 &#39;EventTarget&#39; 上不存在属性 &#39;value&#39;。 React.SyntheticEvent 中不存在“值”<HTMLElement> - Property 'value' does not exist on type 'EventTarget' . "value" is not present in React.SyntheticEvent<HTMLElement> forwardRef 的泛型错误:类型“IntrinsicAttributes”上不存在属性“ref” - Generics error with forwardRef: Property 'ref' does not exist on type 'IntrinsicAttributes'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM