Hello friends, In this blog post we are going to expore a real time senario that I encountered while working on a project. I am going to build a sample project to demo that senario to you and then will share the fix with you.
Real time Senario.
The senario was I want to open a dialog box on some event(lets assume a button click) , This sounds very simple, right, lets build a sample project to implement this.
Create a new project and then add a components folder in src.
npx create-react-app react-forwardref-example --template typescript
I am going to use MUI dialog as a example dialog, next I am going to install MUI in project using below command.
npm install @mui/material @emotion/react @emotion/styled
Next create a new component named “AlertDialog” in component folder and then add the sample code from MUI documentation which you can find it at https://mui.com/material-ui/react-dialog/, then applied some modification as we want to open the dialog from another component and want to keep dialog component seperate too.
Next add a new component file named “Parent.tsx” and add below code in it.
now update the App.tsx as below
Run the application with console open, you should be seeing “Parent Render” log in console.
which tells that the component is rendered. now if you click on “open dialog” button , the dialog box will be opened which the expected behaviour we want to implement and it is working as well but wait, why we are seeing another “Parent Render” log on console, we just wanted to open the dialog.
This indicates that the Parent component is rendering again when we clicking on the “Open Dialog” button and this we do not want as it impact the performance of the compoent if the component is heavy. so, how to fix this?
Improved Code with fix
To fix this problem we can use React forwardref hook .Let us update the AlertDialog component code as below.
import React, { forwardRef, useImperativeHandle } from "react";
import Button from "@mui/material/Button";
import Dialog from "@mui/material/Dialog";
import DialogActions from "@mui/material/DialogActions";
import DialogContent from "@mui/material/DialogContent";
import DialogContentText from "@mui/material/DialogContentText";
import DialogTitle from "@mui/material/DialogTitle";
export interface AlertDialogProps {}
export interface AlertDialogRef {
handleClickOpen: () => void;
}
const AlertDialog = forwardRef<AlertDialogRef, AlertDialogProps>(
function AlertDialog(props, ref) {
const [open, setOpen] = React.useState(false);
useImperativeHandle(ref, () => ({
handleClickOpen() {
setOpen(true);
},
}));
const handleClose = () => {
setOpen(false);
};
return (
<div>
<Dialog
open={open}
onClose={handleClose}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle id="alert-dialog-title">
Use location Services
</DialogTitle>
<DialogContent>
<DialogContentText id="alert-dialog-description">
Let Google help apps determine location. This means sending
anonymous location data to Google, even when no apps are running.
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={handleClose}>Disagree</Button>
<Button onClick={handleClose} autoFocus>
Agree
</Button>
</DialogActions>
</Dialog>
</div>
);
}
);
export default AlertDialog;
Next update the Parent component code as below.
After updating code and running the same, you should see below output.
where we don’t have another re-render for Parent component while opening the dialog and this way we can improve the component perforrance too.
Summary
In this blog post, we explore the usage of forwardRef
in React to prevent unnecessary parent component re-rendering when working with a Dialog component. By leveraging the forwardRef
feature, we can optimize the performance of our React applications. The blog post demonstrates how to create a functional Dialog component that accepts a ref
and utilizes it to access the underlying DOM node. This allows us to interact with the Dialog component without triggering unnecessary re-renders of its parent components. By following the provided example and understanding the power of forwardRef
, developers can efficiently manage component rendering in React and improve overall application performance.