Use Useref to Call Child Component From Parent Component in React With TypeScript

  1. Use useref to Call Child Component From Parent Component in React With TypeScript
  2. Conclusion

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.

New Project

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 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.

App Logs

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.