在 React 自定义挂钩中正确输入 useRef 值
Properly typing useRef values in a React custom hook
我有一个自定义挂钩,在我的 TS 应用程序中 returns 值为 useRef
。不幸的是,它抱怨我要返回的 ref 的类型,我不知道如何正确输入它。
这是我的钩子的样子:
interface MyHookInterface {
someBooleanState: boolean
myRef: HTMLElement | null
}
const useMyHook = (): MyHookInterface => {
const [someBooleanState, setSomeBooleanState] = useState<boolean>(false)
const myRef = useRef<HTMLElement | null>(null)
useEffect(() => {
const el = myRef.current // what type should this be?
// Complaining that el possibly undefined
if(el?.offsetWidth < el?.scrollWidth){
// do stuff
}
}, [])
return {
someBooleanState,
myRef, // Getting: Type 'MutableRefObject<HTMLElement | null>' is missing the following properties from type 'HTMLElement': accessKey, accessKeyLabel, autocapitalize, dir, and 234 more
}
}
正如您在评论中看到的,我的钩子有一些与输入相关的错误:
1- 不知道如何在界面中输入 myRef
。请记住,它将用于多种类型的 HTML 元素,因此我无法在此处指定它是 div 还是什么。
2- 不知道如何输入 el
,但对其属性的访问抱怨它是 undefined
如何在挂钩中正确输入这些值?
发生这种情况是因为 ref 的值存储在“.current”下 属性。
即
const Comp = () => {
...
const refVal = React.useRef(2);
console.log(2 === refVal); // false
console.log(2 === refVal.current); // true
...
}
解决方案取决于您的意图 - 如果您想要 return ref 本身,请按照类型错误的建议将接口类型更改为 MutableRefObject<HTMLElement | null>
,否则,替换 return 值:
return {
someBooleanState,
myRef: myRef.current,
}
如果 el 尚未定义(即如果尚未分配),您可能会收到 undefined
s,因为您使用 ?.
运算符访问 属性 (需要明确的是,这是正确的。
例如
null?.test === undefined; // true
要解决这个问题,请检查 el 是否已定义并且可选(尽管接口定义不需要),检查两个值是否已定义并且都是数字(即使用 el && !isNaN(el?.offsetWidth) && !isNaN(el?.scrollWidth) && el.offsetWidth < el.scrollWidth
。或者,使用如果这适用于您的用例,则无效合并运算符,即 (el?.offsetWidth ?? 0) < (el?.scrollWidth ?? 0)
.
ref 的类型不仅仅是它引用的对象。它是一个 React.MutableRefObject
包装它所引用的内容。这就是提供 current
属性 的原因,因此 ref 可以工作。
如果您仔细考虑 myRef
,您应该会看到您需要的类型。在这种情况下:
React.MutableRefObject<HTMLElement | null>
这让你的钩子 return 输入:
interface MyHookInterface {
someBooleanState: boolean
myRef: React.MutableRefObject<HTMLElement | null>
}
其次,这不起作用的原因:
const el = myRef.current // what type should this be?
// Complaining that el possibly undefined
if(el?.offsetWidth < el?.scrollWidth){
// do stuff
}
是因为你的ref可能还没有被赋值。这意味着 el?.offsetWidth
是 undefined
,因为 el
仍然是 null
。 undefined
不是 <
比较中的有效操作数。 (if (undefined < undefined)
没有多大意义)
您可以通过在进行比较之前检查以确保 el
存在来轻松解决此问题:
if (el && el.offsetWidth < el.scrollWidth){
// do stuff
}
我有一个自定义挂钩,在我的 TS 应用程序中 returns 值为 useRef
。不幸的是,它抱怨我要返回的 ref 的类型,我不知道如何正确输入它。
这是我的钩子的样子:
interface MyHookInterface {
someBooleanState: boolean
myRef: HTMLElement | null
}
const useMyHook = (): MyHookInterface => {
const [someBooleanState, setSomeBooleanState] = useState<boolean>(false)
const myRef = useRef<HTMLElement | null>(null)
useEffect(() => {
const el = myRef.current // what type should this be?
// Complaining that el possibly undefined
if(el?.offsetWidth < el?.scrollWidth){
// do stuff
}
}, [])
return {
someBooleanState,
myRef, // Getting: Type 'MutableRefObject<HTMLElement | null>' is missing the following properties from type 'HTMLElement': accessKey, accessKeyLabel, autocapitalize, dir, and 234 more
}
}
正如您在评论中看到的,我的钩子有一些与输入相关的错误:
1- 不知道如何在界面中输入 myRef
。请记住,它将用于多种类型的 HTML 元素,因此我无法在此处指定它是 div 还是什么。
2- 不知道如何输入 el
,但对其属性的访问抱怨它是 undefined
如何在挂钩中正确输入这些值?
发生这种情况是因为 ref 的值存储在“.current”下 属性。
即
const Comp = () => {
...
const refVal = React.useRef(2);
console.log(2 === refVal); // false
console.log(2 === refVal.current); // true
...
}
解决方案取决于您的意图 - 如果您想要 return ref 本身,请按照类型错误的建议将接口类型更改为 MutableRefObject<HTMLElement | null>
,否则,替换 return 值:
return {
someBooleanState,
myRef: myRef.current,
}
如果 el 尚未定义(即如果尚未分配),您可能会收到 undefined
s,因为您使用 ?.
运算符访问 属性 (需要明确的是,这是正确的。
例如
null?.test === undefined; // true
要解决这个问题,请检查 el 是否已定义并且可选(尽管接口定义不需要),检查两个值是否已定义并且都是数字(即使用 el && !isNaN(el?.offsetWidth) && !isNaN(el?.scrollWidth) && el.offsetWidth < el.scrollWidth
。或者,使用如果这适用于您的用例,则无效合并运算符,即 (el?.offsetWidth ?? 0) < (el?.scrollWidth ?? 0)
.
ref 的类型不仅仅是它引用的对象。它是一个 React.MutableRefObject
包装它所引用的内容。这就是提供 current
属性 的原因,因此 ref 可以工作。
如果您仔细考虑 myRef
,您应该会看到您需要的类型。在这种情况下:
React.MutableRefObject<HTMLElement | null>
这让你的钩子 return 输入:
interface MyHookInterface {
someBooleanState: boolean
myRef: React.MutableRefObject<HTMLElement | null>
}
其次,这不起作用的原因:
const el = myRef.current // what type should this be?
// Complaining that el possibly undefined
if(el?.offsetWidth < el?.scrollWidth){
// do stuff
}
是因为你的ref可能还没有被赋值。这意味着 el?.offsetWidth
是 undefined
,因为 el
仍然是 null
。 undefined
不是 <
比较中的有效操作数。 (if (undefined < undefined)
没有多大意义)
您可以通过在进行比较之前检查以确保 el
存在来轻松解决此问题:
if (el && el.offsetWidth < el.scrollWidth){
// do stuff
}