How to Use Useref to Call Child Component From Parent Component in React With TypeScript
The React documentation defines components as functions that accept random inputs and return React elements. These functions are reusable, independent, and exist in isolation.
These components help us to create a single-page application which means that our application does not need to reload every time an event occurs on a page. The React elements can exist as document object Model(DOM) elements or user-defined components.
The user-defined components have a single object named props
that gets passed to it by React once it finds a component of this type. Note that JSX attributes and their children are passed to the object during its creation.
In this tutorial, we will learn how to call a child component from a parent component of a React application.
Use useref
to Call Child Component From Parent Component in React With TypeScript
Open WebStorm IDEA and select File > New > Project
. On the window that opens, select React on the left side, and on the right side, change the project name from untitled
to typescript-useref
.
And click on the checkbox named Create TypeScript Project.
Ensure you have installed the node
runtime environment so that the Node interpreter
section can be read automatically from the system. The create-react-app
section uses the npx
command to generate dependencies only for local use and not globally.
Use the following image to verify that the application details are correct.
Create an Interface Named UserService
Create a JSX file named UserService.tsx
and copy and paste the following code into the file.
export interface UserService{
greetUser: () => void
}
In this file, we have created an interface named UserService
that declares one method called greetUser()
that does not return any value as indicated by the void
return type. We will use this interface in the following sections to test our application.
Create a Child Component
Create a JSX file named UserComponent.tsx
and copy and paste the following code into the file.
import {forwardRef, Ref, useImperativeHandle} from "react";
import {UserService} from "../common/UserService";
export const UserComponent = forwardRef((props: {userName: string}, ref: Ref<UserService>) => {
const {userName} = props;
function greetUser(){
console.log("Hello "+userName);
}
useImperativeHandle(ref, () => ({greetUser}));
return <div>{userName}</div>
});
In this code, we have used React’s forwardRef()
function to create a component named UserComponent
. This function accepts a render ForwardRefRenderFunction<T, P>
and returns a ForwardRefExoticComponent<PropsWithoutRef<P> & RefAttributes<T>>
.
As we can see from the declarations, P
is of type PropsWithoutRef<P>
and T
is of type RefAttributes<T>
, which is what we have passed as the argument of the render function.
Next, we have added the userName
attribute to the props object of our UserComponent
, {userName} = props
, and created a method named greetUser()
after it to log the argument passed as the value of the attribute to the console.
We have used React’s useImperativeHandle()
function to call this method. Note that we have passed our Ref<UserService>
as the argument of the first parameter, and the second argument is simply the implementation of the UserService
interface.
This is because the type of the second argument must inherit from the first argument passed to the React function. Finally, our component returns an element that contains the value of the userName
attribute.
Create a Parent Component
In this section, we will use the root component App.tsx
as the parent to the child component we created in the previous example. Copy and paste the following code into the App.tsx
file.
import React, {useRef} from 'react';
import './App.css';
import {UserService} from "./common/UserService";
import {UserComponent} from "./components/UserComponent";
function App() {
const ref = useRef<UserService>(new class implements UserService {
greetUser(): void {
console.log("Hello John")
}
})
const onButtonClick = () => {
if (ref.current){
ref.current.greetUser();
}
}
return (
<div className="App">
<UserComponent userName={"Doe"} ref={ref}/>
<button onClick = {onButtonClick}>Greet user</button>
</div>
);
}
export default App;
In this file, we use the root component App
to call our child component UserComponent
using React’s useRef()
function. The function accepts an initial value of type UserService
or null
and returns a MutableRefObject
.
We have declared an instance of the UserService
as the function’s argument. Note that this default function will be called if we do not pass a MutableRefObject
to the child component, which uses the name ref
.
To call the child component from the parent component, we have added the <UserComponent>
tag inside the return
statement and passed the argument of the userName
attribute as the string "Doe"
.
The parent component defines a button that invokes the onButtonClick()
method when clicked. The method uses the current
object to replace the initial value with the value of the greetUser()
method defined by the UserComponent
.
As a result, the application logs Hello Doe
to the console. Note that if we omit the ref
attribute from the <UserComponent>
, the application will log Hello John
to the console.
To verify whether this application is working as expected, use the following command to run the application.
~/WebstormProjects/typescript-useref$ npm start
The above command starts the server on localhost
(http://localhost:3000) using port 3000, and we can use the information to access the web page. When the web page opens, we find that we can display both the child component and the parent component.
Note that the child component displays a <div>
tag with a text and the text is the value of the userName
attribute. Click the button labeled Greet user
and press the shortcut Shift+CTRL+J on your computer to view the value logged to the console on your browser.
Ensure the output of the application is as shown in the following image.
Conclusion
In this tutorial, we learned how to call a child component from a parent component using React’s useRef()
function. Note that we have used TypeScript to test this application, and we can also use JavaScript depending on the requirement, as the approach is still the same though the implementation details might differ.
David is a back end developer with a major in computer science. He loves to solve problems using technology, learning new things, and making new friends. David is currently a technical writer who enjoys making hard concepts easier for other developers to understand and his work has been published on multiple sites.
LinkedIn GitHub