打字稿:React Native useRef 给出错误“对象可能为空”

Posted

技术标签:

【中文标题】打字稿:React Native useRef 给出错误“对象可能为空”【英文标题】:Typescript: React Native useRef giving error "Object is possibly null" 【发布时间】:2022-01-08 11:58:33 【问题描述】:

我在视图上使用 ref。打字稿给我一个错误“对象可能是‘空’”。视图上使用的 ref 的正确类型是什么?具体来说,我使用的是Animated.View,但我认为这没有什么不同。

此处的其他答案适用于 ReactJS(web) 并使用 const overlayEl = useRef<htmlDivElement>(null);,但我正在寻找 React Native 的答案。

const Component = () => 
  const ref = React.useRef(null);

  React.useLayoutEffect(()=>
    console.log(ref.current.clientHeight); 
    // ^ Error: "Object is possibly null" on the `ref.current` portion
  ,[]);

  return (
    <Animated.View ref=ref style=height: 100></Animated.View>
  );

我尝试过的事情:

const ref = React.useRef<React.FunctionComponent>(null);
const ref = React.useRef<React.ReactElement>(null);
const ref = React.useRef<React.MutableRefObject<null>>(null);
const ref = React.useRef(null) as React.MutableRefObject<null>;
console.log(ref?.current?.clientHeight); 
// ^ Error: Property clientHeight does not exist on type 'never'

唯一有效的是这个,但这并不是真正的正确修复

  React.useLayoutEffect(()=>
    const current = ref?.current ||  clientHeight: 0 ; 
    console.log(ref.current.clientHeight);
  ,[]);

【问题讨论】:

唯一有效的是这个,但这并不是真正的正确修复你认为什么是正确的修复? 如果有办法通过在 useRef 声明中正确设置类型来解决它,那么对我来说,这是正确的解决方法。我想我根本不知道正确的类型是什么。如果没有打字来解决它,那么我想我上面写的就是正确的解决方法。 好吧 useRef(null) 有效地返回一个具有 null 当前属性的 ref,TypeScript 在执行代码之前会警告您,因此您必须使用空检查或可选的链接运算符对其进行调整就像你做的那样 我明白了。并且将 useRef() 不带 null 并没有什么区别,因为它仍然是未定义的。如果您对此做出回应,我可以接受您的评论作为答案。谢谢 useLayoutEffect 在渲染之前运行,这就是您的 ref 为空的原因。有什么理由使用React.useLayoutEffect 而不是React.useEffect 【参考方案1】:

我不认为它真的是 TypeScript 问题,而更多的是初始化问题。当您尝试访问您的 ref 时,您会以访问对象及其 null 而不是对象的方式这样做,从而引发您得到的错误。 您可以验证 ref 是否为空,或者将其初始化为某个对象,以便您可以正确查询其属性:

// this
const ref = React.useRef();



// or this
const ref = React.useRef(null);
React.useLayoutEffect(()=>
    if(ref.current !== null)
       //do stuff
    
  ,[]);

【讨论】:

这是有道理的。但是当我把它放在if ( ref.current !== null ) ... 里面时,我得到了错误:“属性'clientHeight'不存在于类型中”【参考方案2】:

这是useRef 在 React 中的输入方式:

function useRef<T>(initialValue: T): MutableRefObject<T>;

interface MutableRefObject<T> 
    current: T;

这意味着一旦输入MutableRefObject,它就会始终保持其类型,因此您必须使用尖括号正确输入:

const ref = React.useRef<React.ElementRef<typeof View> | null>(null);

【讨论】:

在将其更改为 View 并按照您的说明定义 ref 后,仍然出现“属性 View 上不存在属性 clientHeight”的错误。我想我只需要像您在 cmets 中指出的那样明确定义它。或者,也使它消失的是const ref= React.useRef&lt;any&gt;(null);,根据this question,但有些人可能会质疑这有多合适。考虑到我们讨论的所有其他内容,我可以在这个阶段接受这一点 这就是为什么我问你 clientHeight 是否存在于 React Native 中,因为我认为它不存在。您可以坚持使用 any 解决方案,但您必须知道 any 类型是一种解决方法,它只是完全禁用 TypeScript 的类型检查,就像您编写纯 javascript 一样

以上是关于打字稿:React Native useRef 给出错误“对象可能为空”的主要内容,如果未能解决你的问题,请参考以下文章

React hook useRef 不适用于样式化组件和打字稿

尝试在打字稿中使用 React useref 时出错

在自定义输入元素上使用带有打字稿的 useRef

手动设置电流时,我在 useRef() 钩子上使用啥打字稿类型?

javascript React Native打字稿配置

如何为 react-native 本机 ui 组件创建打字稿类型定义?