Forwarding Refs In React

This article was originally published on my blog.
 
In this article, we will be discussing another concept about Refs called Forwarding Refs. But before understanding Forwarding Refs we have to first understand what ref is, why we have to use it and how to create it. In my previous article, I have already discussed what the heck  Refs are and what are the different ways to create refs in React. If you don't know about refs then you can read my article here. 
While writing React apps,  in some situations we have to pass a ref from the parent component to its child component to get access to DOM element of the child component. We know that in React data flows from top to bottom with the help of props. So if we have to change the behavior of child component then we can pass props from parent to its child.
 
According to the React documentation,
 
Ref forwarding is a technique for automatically passing a ref through a component to one of its children. This is typically not necessary for most components in the application. However, it can be useful for some kinds of components, especially in reusable component libraries. 
 
TL;DR

Forwarding Ref with React.forwardRef()

 
As you pass data using props to the child components, we can pass ref in the same way. So first we will create two components as below:
  1. import React, { Component } from "react";  
  2. import Input from "./Input";  
  3.   
  4. export default function CreateRefApiExample() {  
  5.   return (  
  6.     <div style={{ border: "1px solid red", width: "400px" }}>  
  7.       <b>Parent Component</b>  
  8.       <br />  
  9.       <br />  
  10.       <Input />  
  11.       <button style={{ margin: "8px" }}>Click!</button>  
  12.     </div>  
  13.   );  
  14. }  
CreateRefApiExample is our parent component.
  1. import React from "react";  
  2.   
  3. export default function Input() {  
  4.   return (  
  5.     <div style={{ border: "1px solid green", width:"300px", margin:"16px" }}>  
  6.       Child Component  
  7.       <br />  
  8.       Name: <input type="text" style={{ margin: "32px 0 32px 0" }} />  
  9.     </div>  
  10.   );  
  11. }  
Input is the child component. So after running code, it looks like as below,
 
Forwarding Refs In React
Input component is the child component to the CreateRefApiExample. So now what we want is when we click on the button in CreateRefApiExample; i.e parent component, then input field in Input component should be focused. So to achieve this we have to create a ref in parent component and pass it to the child component and when a user clicks on the button then we have to makethe input focused.
 
Let's first create a ref in parent component using React.createRef() api. 
  1. let inputRef = React.createRef();  
and pass it down to the child component.
  1. import React, { Component } from "react";  
  2. import Input from "./Input";  
  3.   
  4. export default function CreateRefApiExample() {  
  5.   let inputRef = React.createRef();  
  6.   
  7.   return (  
  8.     <div style={{ border: "1px solid red", width: "400px" }}>  
  9.       <b>Parent Component</b>  
  10.       <br />  
  11.       <br />  
  12.       <Input ref={inputRef} />  
  13.       <button style={{ margin: "8px" }}>Click!</button>  
  14.     </div>  
  15.   );  
  16. }  
The next step is how to receive this ref in our Input component and assign it to the input tag. This can be done using React.forwardRef() API. First, wrap our Input component with React.forwardRef function which will now give us access to the ref that we have passed to this component.
  1. import React from "react";  
  2.   
  3. export default React.forwardRef(function Input(props, ref) {  
  4.   return (  
  5.     <div style={{ border: "1px solid green", width:"300px", }}>  
  6.       Child Component  
  7.       <br />  
  8.       Name: <input   
  9.               type="text"  
  10.               ref={ref}   
  11.               style={{ margin: "32px 0 32px 0" }} />  
  12.     </div>  
  13.   );  
  14. })  
Observe that ref is not part of props; it will be passed as a separate parameter along with props due to React.forwardRef() API.
 
At this point, we have created a new ref; i.e inputRef, and forwarded it to the Input component. Now the next step is we have to access the ref in parent component and trigger its focus event when a user clicks on the button.
 
Create a onClick handler function as below
  1. const handleClick = () => {  
  2.    inputRef.current.focus();  
  3.  };  
and bind it to the button onClick event.
  1. import React, { Component } from "react";  
  2. import Input from "./Input";  
  3.   
  4. export default function CreateRefApiExample() {  
  5.   let inputRef = React.createRef();  
  6.   
  7.   const handleClick = () => {  
  8.     inputRef.current.focus();  
  9.   };  
  10.   
  11.   return (  
  12.     <div style={{ border: "1px solid red", width: "400px" }}>  
  13.       <b>Parent Component</b>  
  14.       <br />  
  15.       <br />  
  16.       <Input ref={inputRef} />  
  17.       <button style={{ margin: "8px" }} onClick={handleClick}>  
  18.         Click!  
  19.       </button>  
  20.     </div>  
  21.   );  
  22. }  
Run the application and see the output,
Forwarding Refs In React
 
You can do this same thing using useRef() hook as well. If you want to try with hooks then just create ref using useRef() instead of React.createRef() API and other code remains the same.  
  1. import React, { useRef } from "react";  
  2. import Input from "./Input";  
  3.   
  4. export default function CreateRefApiExample() {  
  5.   //let inputRef = React.createRef();  
  6.   
  7.   let inputRef = useRef(null);  
  8.   
  9.   const handleClick = () => {  
  10.     inputRef.current.focus();  
  11.   };  
  12.   
  13.   return (  
  14.     <div style={{ border: "1px solid red", width: "400px" }}>  
  15.       <b>Parent Component</b>  
  16.       <br />  
  17.       <br />  
  18.       <Input ref={inputRef} />  
  19.       <button style={{ margin: "8px" }} onClick={handleClick}>  
  20.         Click!  
  21.       </button>  
  22.     </div>  
  23.   );  
  24. }  

Conclusion

 
In this article, I have explained about Forwarding Refs in React JS and also created simple examples using ref.
 
I really hope that you enjoyed this article, and please do not hesitate to send me your thoughts or comments about what could I have done better.
 
You can follow me on twitter @sumitkharche01
 
Happy Coding!