处理用 TypeScript 编写的 React 功能组件中的 Ref:Element is not assignable 错误

Posted

技术标签:

【中文标题】处理用 TypeScript 编写的 React 功能组件中的 Ref:Element is not assignable 错误【英文标题】:Handling Ref in React Functional Component written in TypeScript: Element is not assignable error 【发布时间】:2020-10-02 19:38:43 【问题描述】:

我的以下代码可能存在语法问题。 elementRefdiv 的代码底部更新为 ref attr,linting 告诉我:

let elementRef: React.MutableRefObject<null>
Type 'htmlDivElement | null' is not assignable to type 'MutableRefObject<null>'.
  Type 'null' is not assignable to type 'MutableRefObject<null>'.ts(2322)

我显然不了解 createRef 的工作原理,希望得到一些指导。

FC 代码:

interface VerticalNavExpansionPanelInterface 
    location: any;
    item: any;
    key: any;
    children: any;
  

  const VerticalNavExpansionPanel: React.FC<VerticalNavExpansionPanelInterface> = ( location, item, key, children ) => 
    const [collapsed, toggleCollapsed] = React.useState(true)

    let history = useHistory();
    //let elementRef = React.createRef();
    let elementRef = React.useRef(null);

    let componentHeight = 0;

    const handleClick = () => 
      toggleCollapsed(!collapsed);
    ;

    const calcaulateHeight = (node: any) => 
      if (node.name !== "child") 
        for (let child of node.children) 
          calcaulateHeight(child);
        
      
      componentHeight += node.clientHeight;
      return;
    ;
    React.useEffect(() => 
      calcaulateHeight(elementRef);
      // // OPEN DROPDOWN IF CHILD IS ACTIVE
      for (let child of elementRef.children) 
        if (child.getAttribute("href") === location.pathname) 
          toggleCollapsed(false);
        
      
    );

    return (
      <div>
        <TouchRipple
          className="nav-item flex-middle h-48 w-100"
          onClick=() => handleClick()
        >
          <div>
            <Icon className="text-middle item-icon">item.icon</Icon>
            <span className="text-middle pl-20 item-text">item.name</span>
          </div>
          item.badge && (
            <div className=`badge bg-$item.badge.color`>item.badge.value</div>
          )
          <div
            className=
              collapsed
                ? classes.collapseIcon + " item-arrow"
                : classes.expandIcon + " item-arrow"
            
          >
            <Icon className="text-middle">chevron_right</Icon>
          </div>
        </TouchRipple>

        <div
          ref=(el) => (elementRef = el)
          className="submenu"
          style=
            collapsed
              ?  maxHeight: "0px" 
              :  maxHeight: componentHeight + "px" 
          
        >
          children
        </div>
      </div>
    );
  ;

【问题讨论】:

【参考方案1】:

您必须为 useRef 指定一个明确的类型,即要引用的 HTML 标记的类型:

const elementRef = React.useRef<HTMLDivElement>(null);

另外,请注意,引用的唯一有效属性是current,它检索引用的当前值。所以你可能想改变:

elementRef.children

到:

elementRef.current.children

并在您访问参考属性的任何地方进行类似的更改。

【讨论】:

以上是关于处理用 TypeScript 编写的 React 功能组件中的 Ref:Element is not assignable 错误的主要内容,如果未能解决你的问题,请参考以下文章

将函数作为道具传递给 Typescript React 功能组件

如何在 TypeScript 中为 React Apollo Query 组件编写 HOC?

入门TypeScript编写React

如何在用 TypeScript (TSX) 编写的 React 应用程序中使用 Facebook Relay?

如何测试使用自定义TypeScript React Hook的组件?

在 React TypeScript 组件中导入 Javascript