React - useRef with TypeScript and functional component


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> ); } 
0

Just replace the declaration of your ref with this const ref = useRef<{ SayHi: () => void }>(null);

0

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like