I was trying to call the child component method from parent component and I was trying to use useRef. In the future, the SayHi method will be update hook state in the child component. Unfortunately, I have bugs with I can't deal with.
Line: ref.current.SayHi();
Property 'SayHi' does not exist on type 'ForwardRefExoticComponent<{ name: string; } & RefAttributes<{ SayHi: () => void; }>>'.
Line: < Child name="Adam" ref={ref}/>
Type 'RefObject void; }>>>' is not assignable to type '((instance: { SayHi: () => void; } | null) => void) | RefObject<{ SayHi: () => void; }> | null | undefined'. Type 'RefObject void; }>>>' is not assignable to type 'RefObject<{ SayHi: () => void; }>'. Property 'SayHi' is missing in type 'ForwardRefExoticComponent<{ name: string; } & RefAttributes<{ SayHi: () => void; }>>' but required in type '{ SayHi: () => void; }'.
Full test.tsx file:
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>; }); I deeply ask for help on this topic.
2 Answers
You require to extract the ref type elsewhere:
interface RefObject { SayHi: () => void } then just refer to it in both places
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> ); } 0Just replace the declaration of your ref with this const ref = useRef<{ SayHi: () => void }>(null);