【问题标题】:Passing a union type into React's useRef doesn't work将联合类型传递给 React 的 useRef 不起作用
【发布时间】:2020-01-29 15:15:02
【问题描述】:

React 的useRef 类型实现不允许我使用联合类型有什么原因吗?

我在 TS 方面不是很有经验,因此无法完全理解错误的原因和底层类型。

TS playground

function Test() {
    const ref = React.useRef<HTMLInputElement | HTMLButtonElement>(null);

    return Math.random()
        ? <input ref={ref} />
        : <button ref={ref}></button>;        
}

错误:

Type 'RefObject<HTMLInputElement | HTMLButtonElement>' is not assignable to type 'string | ((instance: HTMLButtonElement | null) => void) | RefObject<HTMLButtonElement> | null | undefined'.
  Type 'RefObject<HTMLInputElement | HTMLButtonElement>' is not assignable to type 'RefObject<HTMLButtonElement>'.
    Type 'HTMLInputElement | HTMLButtonElement' is not assignable to type 'HTMLButtonElement'.
      Type 'HTMLInputElement' is not assignable to type 'HTMLButtonElement'.
        Types of property 'labels' are incompatible.
          Type 'NodeListOf<HTMLLabelElement> | null' is not assignable to type 'NodeListOf<HTMLLabelElement>'.
            Type 'null' is not assignable to type 'NodeListOf<HTMLLabelElement>'.  TS2322

React 的类型(这样你就不需要查找它们):

interface ClassAttributes<T> extends Attributes {
    ref?: LegacyRef<T>;
}

type Ref<T> = { bivarianceHack(instance: T | null): void }["bivarianceHack"] | RefObject<T> | null;
type LegacyRef<T> = string | Ref<T>;

function useRef<T>(initialValue: T|null): RefObject<T>;

interface RefObject<T> {
    readonly current: T | null;
}

【问题讨论】:

    标签: reactjs typescript react-hooks


    【解决方案1】:

    试试这样:

    import React from 'react';
    
    function Test() {
        const ref = React.useRef<HTMLInputElement | HTMLButtonElement | null>(null);
    
        return Math.random()
            ? <input ref={(instance) => ref.current = instance} />
            : <button ref={(instance) => ref.current = instance}></button>;        
    }
    

    如果您有严格的 null 检查,则需要指定 null(所有类型都没有 undefiened | null)+ ref 有多个签名,因此 typescript 无法确定正确的一个。

    【讨论】:

    • 谢谢。为什么从联合类型中省略null 然后使ref.current = instancereadonly 上失败检查超出了我的范围:)
    猜你喜欢
    • 1970-01-01
    • 2021-04-02
    • 2019-05-28
    • 2021-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-23
    • 1970-01-01
    相关资源
    最近更新 更多