为任何类型的 HTML 元素键入自定义 useRef 挂钩
Typing a custom useRef hook for any type of HTML element
我对 Typescript 还是有点陌生,我的目标是在 Typescript 中创建一个自定义 React.useRef
挂钩,returns 一个引用。我希望为任何 HTML 元素键入此 ref 而不仅仅是按钮。我 运行 遇到了正确输入此自定义挂钩的问题。
这是我的钩子:
type CustomRefHook = (dependencies?: string | boolean | number[]) => React.MutableRefObject<HTMLButtonElement | null>;
const useCustomRefHook: CustomRefHook = (...dependencies) => {
const ref = React.useRef<HTMLButtonElement | null>(null);
useEffect(() => {
// ... do stuff
}, dependencies)
return ref;
}
目前,我对这个钩子的大部分用例都是按钮,但我想最终将其扩展到任何类型的 HTML 元素。我试过使用 HTMLElement
而不是 HTMLButtonElement
,但是我得到一个类型错误:
Type 'MutableRefObject<HTMLElement | null>' is not assignable to type 'string | ((instance: HTMLButtonElement | null) => void) | RefObject<HTMLButtonElement> | null | undefined'.
Type 'MutableRefObject<HTMLElement | null>' is not assignable to type 'RefObject<HTMLButtonElement>'.
Types of property 'current' are incompatible.
Type 'HTMLElement | null' is not assignable to type 'HTMLButtonElement | null'.
每当我尝试将此引用附加到按钮时。使用 HTMLButtonElement
消除 Typescript 错误,但我再次希望这个钩子能够处理任何类型的 HTML 元素。
ref
的类型需要与它所附加的 DOM 元素完全匹配,因此您需要使用泛型来指定元素类型。
由于 useCustomRefHook
现在是一个泛型函数,声明内联类型比声明为单独的类型更有意义 CustomRefHook
.
我已允许此挂钩接受 T
的 any
值,但如果您只想将其应用于 HTML 元素,则可以使用 T extends HTMLElement
。这可能很重要,具体取决于 useEffect
中“做事”的内容。如果“做事”需要关于 T
的任何特定内容,那么您需要确保 T
使用所需的 properties/methods.
扩展某些内容
import React, { MutableRefObject, DependencyList, useEffect, useRef } from "react";
const useCustomRefHook = <T extends any>( dependencies: DependencyList = [] ): MutableRefObject<T | null> => {
const ref = useRef<T | null>(null);
useEffect(() => {
// ... do stuff
}, dependencies);
return ref;
};
挂钩 returns 一个基于通用 T
的 MutableRefObject<T | null>
。 T
的值不可能从参数中推断出来,因此每次调用它时都需要指定泛型。
const Test = () => {
const ref = useCustomRefHook<HTMLButtonElement>();
return <button ref={ref} />;
};
我对 Typescript 还是有点陌生,我的目标是在 Typescript 中创建一个自定义 React.useRef
挂钩,returns 一个引用。我希望为任何 HTML 元素键入此 ref 而不仅仅是按钮。我 运行 遇到了正确输入此自定义挂钩的问题。
这是我的钩子:
type CustomRefHook = (dependencies?: string | boolean | number[]) => React.MutableRefObject<HTMLButtonElement | null>;
const useCustomRefHook: CustomRefHook = (...dependencies) => {
const ref = React.useRef<HTMLButtonElement | null>(null);
useEffect(() => {
// ... do stuff
}, dependencies)
return ref;
}
目前,我对这个钩子的大部分用例都是按钮,但我想最终将其扩展到任何类型的 HTML 元素。我试过使用 HTMLElement
而不是 HTMLButtonElement
,但是我得到一个类型错误:
Type 'MutableRefObject<HTMLElement | null>' is not assignable to type 'string | ((instance: HTMLButtonElement | null) => void) | RefObject<HTMLButtonElement> | null | undefined'.
Type 'MutableRefObject<HTMLElement | null>' is not assignable to type 'RefObject<HTMLButtonElement>'.
Types of property 'current' are incompatible.
Type 'HTMLElement | null' is not assignable to type 'HTMLButtonElement | null'.
每当我尝试将此引用附加到按钮时。使用 HTMLButtonElement
消除 Typescript 错误,但我再次希望这个钩子能够处理任何类型的 HTML 元素。
ref
的类型需要与它所附加的 DOM 元素完全匹配,因此您需要使用泛型来指定元素类型。
由于 useCustomRefHook
现在是一个泛型函数,声明内联类型比声明为单独的类型更有意义 CustomRefHook
.
我已允许此挂钩接受 T
的 any
值,但如果您只想将其应用于 HTML 元素,则可以使用 T extends HTMLElement
。这可能很重要,具体取决于 useEffect
中“做事”的内容。如果“做事”需要关于 T
的任何特定内容,那么您需要确保 T
使用所需的 properties/methods.
import React, { MutableRefObject, DependencyList, useEffect, useRef } from "react";
const useCustomRefHook = <T extends any>( dependencies: DependencyList = [] ): MutableRefObject<T | null> => {
const ref = useRef<T | null>(null);
useEffect(() => {
// ... do stuff
}, dependencies);
return ref;
};
挂钩 returns 一个基于通用 T
的 MutableRefObject<T | null>
。 T
的值不可能从参数中推断出来,因此每次调用它时都需要指定泛型。
const Test = () => {
const ref = useCustomRefHook<HTMLButtonElement>();
return <button ref={ref} />;
};