如何在Typescript中使用React useRef钩子?

时间:2019-01-29 12:11:11

标签: reactjs typescript typescript-typings react-hooks

使用新的useRef钩子创建引用

const anchorEl = React.useRef<HTMLDivElement>(null)

并使用类似

<div style={{ width: "15%", ...flexer, justifyContent: "flex-end" }}>
    <Popover
        id="simple-popper"
        open={open}
        anchorEl={anchorEl}
        onClose={() => {
          setOpen(false)
        }}
        anchorOrigin={{
          vertical: 'bottom',
          horizontal: 'center',
        }}
        transformOrigin={{
          vertical: 'top',
          horizontal: 'center',
        }}
    >
        <Typography>The content of the Popover.</Typography>
    </Popover>
</div>
<div ref={anchorEl} >
      ...

但是我得到这个错误

TS2322: Type 'MutableRefObject<HTMLDivElement>' is not assignable to type 'HTMLElement | ((element: HTMLElement) => HTMLElement)'.
  Type 'MutableRefObject<HTMLDivElement>' is not assignable to type '(element: HTMLElement) => HTMLElement'.
    Type 'MutableRefObject<HTMLDivElement>' provides no match for the signature '(element: HTMLElement): HTMLElement'.
Version: typescript 3.2.2, tslint 5.12.0

1 个答案:

答案 0 :(得分:2)

anchorEl变量是ref对象,即仅具有current属性的对象。 Popover的工作方式尚不清楚,但是它期望一个元素作为anchorEl的道具,而不是参考。

应该是:

如果<Popover<div ref={anchorEl} >是如图所示的同级兄弟,那么当ref作为道具传递时,它就不能准备使用。在这种情况下,需要在挂载时重新渲染组件:

const [, forceUpdate] = useState();

useEffect(() => {
  forceUpdate();
}, []);

...

   { anchorEl.current && <Popover
        id="simple-popper"
        open={open}
        anchorEl={anchorEl.current}
        ...
   }
   <div ref={anchorEl} >

如果<div ref={anchorEl} >不必呈现为DOM,则可能是

   <Popover
        id="simple-popper"
        open={open}
        anchorEl={<div/>}

需要两次渲染一个组件并使用forceUpdate解决方法表明,可以通过更好的方法来完成此操作。这里的实际问题是Popover接受元素作为道具,而接受引用在React中很常见。