我试图从父组件调用子组件方法,并且试图使用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>;
});
我对此主题深有帮助。
答案 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);