React-带TypeScript和功能组件的useRef

时间:2020-03-05 22:21:56

标签: reactjs typescript ref tsx react-functional-component


我试图从父组件调用子组件方法,并且试图使用useRef。将来,SayHi方法将更新子组件中的挂钩状态。不幸的是,我有一些无法解决的错误。

行: ref.current.SayHi();

类型'ForwardRefExoticComponent <{不存在属性'SayHi'<名称:字符串; }&RefAttributes <{SayHi:()=> void; } >>'。

行: <子名称=“ Adam” ref = {ref} />

输入'RefObject void; } >>>'不能分配给类型'((实例:{SayHi:()=> void;} | null)=> void)| RefObject <{SayHi:()=>无效; }> |空|未定义”。 输入'RefObject void; } >>>'不能分配给'RefObject <{SayHi:()=> void; }>'。 类型'ForwardRefExoticComponent <{name:string;中缺少属性'SayHi' }&RefAttributes <{SayHi:()=> void; } >>”,但类型为“ {{SayHi:()=> void; }'。


完整的test.tsx文件:

import React, { useRef, forwardRef, useImperativeHandle, Ref } from 'react'

const Parent = () => {
    const ref = useRef<typeof Child>(null);
    const onButtonClick = () => {
      if (ref.current) {
        ref.current.SayHi();
      }
    };
    return (
      <div>
        <Child name="Adam" ref={ref}/>
        <button onClick={onButtonClick}>Log console</button>
      </div>
    );
  }

const Child = forwardRef((props: {name: string}, ref: Ref<{SayHi: () => void}>)=> {
  const {name} = props;
  useImperativeHandle(ref, () => ({ SayHi }));

  function SayHi() { console.log("Hello " + name); }

  return <div>{name}</div>;
});

我对此主题深有帮助。

2 个答案:

答案 0 :(得分:23)

您需要在其他位置提取引用类型:

interface RefObject {
  SayHi: () => void
}

然后在两个地方都引用它

const Child = forwardRef((props: {name: string}, ref: Ref<RefObject>)=> {
  const {name} = props;  
  useImperativeHandle(ref, () => ({ SayHi }));
  function SayHi() { console.log("Hello " + name); }

  return <div>{name}</div>;
});
const Parent = () => {
    const ref = useRef<RefObject>(null);
    const onButtonClick = () => {
      if (ref.current) {
        ref.current.SayHi();
      }
    };
    return (
      <div>
        <Child name="Adam" ref={ref}/>
        <button onClick={onButtonClick}>Log console</button>
      </div>
    );
}

答案 1 :(得分:1)

只需将您的ref的声明替换为此const ref = useRef<{ SayHi: () => void }>(null);