Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 991
Adam Nowicki Avatar asked Mar 05 '20 22:03

Adam Nowicki


People also ask

Can I use useRef in functional component?

The useRef is a hook that allows to directly create a reference to the DOM element in the functional component. Syntax: const refContainer = useRef(initialValue); The useRef returns a mutable ref object.

How do I use a useRef hook in TypeScript?

To use useRef with TypeScript, it is actually pretty easy, all you need to do is provide the type that you want to the function via open and closed chevrons like you would with other React hooks like so: const myRef = useRef<number>(0) .

How do I use TypeScript REF IN React?

To use refs with functional components use a special useRef hook. It is a generic function, so we can pass a type-parameter, that will tell TypeScript what type is acceptable for this ref. // using `HTMLInputElement` as a type parameter. // to bind the element with the ref.

How do you use REF in functional component React?

To create a ref in a functional component we use the useRef() hook which returns a mutable object with a . current property set to the initialValue we passed to the hook. This returned object will persist for the full lifetime of the component. Thus, throughout all of its re-rendering and until it unmounts.


1 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>     ); } 
like image 125
Federkun Avatar answered Oct 03 '22 12:10

Federkun