如何在 React Typescript 中输入动态标签元素的 refObject?

问题描述 投票:0回答:1

这个问题不断重复出现,我似乎总是围绕它编写代码,所以我希望有人可以帮助我阐明输入此问题的正确方法。

function MyComponent({ isCondition }): Props { {
  const ElementType: React.ElementType = isCondition ? 'a' : 'div'
  const ref = useRef<HTMLAnchorElement | HTMLDivElement>(null)

return (
  <ElementType ref={ref}>
    {/* other stuff */}
  </ElementType>
)
}

我不断收到打字稿错误:

Type 'RefObject<HTMLAnchorElement | HTMLDivElement>' is not assignable to type '((string | ((instance: HTMLAnchorElement | null) => void) | RefObject<HTMLAnchorElement>) & (string | RefObject<HTMLDivElement> | ((instance: HTMLDivElement | null) => void))) | null | undefined'.
  Type 'RefObject<HTMLAnchorElement | HTMLDivElement>' is not assignable to type 'RefObject<HTMLAnchorElement> & ((instance: HTMLDivElement | null) => void)'.
    Type 'RefObject<HTMLAnchorElement | HTMLDivElement>' is not assignable to type 'RefObject<HTMLAnchorElement>'.
      Type 'HTMLAnchorElement | HTMLDivElement' is not assignable to type 'HTMLAnchorElement'.
        Type 'HTMLDivElement' is missing the following properties from type 'HTMLAnchorElement': charset, coords, download, hreflang, and 21 more.ts(2322)

我似乎无法输入,以便 Typescript 理解引用的类型将与 JSX 标签匹配。

我看到另一篇文章建议使用 refs,信息会向后流动,并且配置此功能以便打字稿不会抱怨的唯一方法是类型断言或依靠 ref 回调选项。

<ElementType ref={node => ref.current = node}>

这会产生错误

Cannot assign to 'current' because it is a read-only property.ts(2540)

并且节点参数还抱怨它隐式键入“any”

任何人都可以解释什么是打字错误或者我如何看待这个错误吗?

reactjs typescript dynamic callback ref
1个回答
0
投票

你可以尝试这样的事情:

import React, { useRef, ElementType as ElementTypeProp } from 'react';

type Props<T extends ElementTypeProp> = {
  isCondition: boolean;
  as?: T;
};

const MyComponent = <T extends ElementTypeProp = 'div'>({ isCondition, as }: Props<T>) => {
  const ElementType = as || (isCondition ? 'a' : 'div');
  const ref = useRef<T extends 'a' ? HTMLAnchorElement : HTMLDivElement>(null);

  return <ElementType ref={ref}>Hello</ElementType>;
};

export default MyComponent;
© www.soinside.com 2019 - 2024. All rights reserved.