DEV Community

Cover image for Forwarding Refs in React
Sumit Kharche
Sumit Kharche

Posted on • Updated on

Forwarding Refs in React

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 is ref, why we have to use it and how to create it. In my previous article, I have already discussed what the heck is Refs 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 app in some of the situations where 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 flow from top to bottom with the help of props. So if we have to change the behaviour of child component then we can pass props from parent to it 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 in the same way we can pass ref also. So first we will create two components as below:



import React, { Component } from "react";
import Input from "./Input";

export default function CreateRefApiExample() {
  return (
    <div style={{ border: "1px solid red", width: "400px" }}>
      <b>Parent Component</b>
      <br />
      <br />
      <Input />
      <button style={{ margin: "8px" }}>Click!</button>
    </div>
  );
}



Enter fullscreen mode Exit fullscreen mode

CreateRefApiExample is our parent component.



import React from "react";

export default function Input() {
  return (
    <div style={{ border: "1px solid green", width:"300px", margin:"16px" }}>
      Child Component
      <br />
      Name: <input type="text" style={{ margin: "32px 0 32px 0" }} />
    </div>
  );
}



Enter fullscreen mode Exit fullscreen mode

Input is the child component. So after running code, it looks like as below:

Alt Text

If you see Input component is the child component to the CreateRefApiExample. So now what we want is when we click on click 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 button then we have to make input to focus.

Lets first create a ref in parent component using React.createRef() api.



 let inputRef = React.createRef();


Enter fullscreen mode Exit fullscreen mode

and pass it down to the child component.



import React, { Component } from "react";
import Input from "./Input";

export default function CreateRefApiExample() {
  let inputRef = React.createRef();

  return (
    <div style={{ border: "1px solid red", width: "400px" }}>
      <b>Parent Component</b>
      <br />
      <br />
      <Input ref={inputRef} />
      <button style={{ margin: "8px" }}>Click!</button>
    </div>
  );
}



Enter fullscreen mode Exit fullscreen mode

Next step is how to receive this ref in our Input component and assign it to 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.



import React from "react";

export default React.forwardRef(function Input(props, ref) {
  return (
    <div style={{ border: "1px solid green", width:"300px", }}>
      Child Component
      <br />
      Name: <input 
              type="text"
              ref={ref} 
              style={{ margin: "32px 0 32px 0" }} />
    </div>
  );
})



Enter fullscreen mode Exit fullscreen mode

Observed that ref is not the 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 new ref i.e inputRef and forward it to the Input component. Now 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



 const handleClick = () => {
    inputRef.current.focus();
  };


Enter fullscreen mode Exit fullscreen mode

and bind it to the button onClick event.



import React, { Component } from "react";
import Input from "./Input";

export default function CreateRefApiExample() {
  let inputRef = React.createRef();

  const handleClick = () => {
    inputRef.current.focus();
  };

  return (
    <div style={{ border: "1px solid red", width: "400px" }}>
      <b>Parent Component</b>
      <br />
      <br />
      <Input ref={inputRef} />
      <button style={{ margin: "8px" }} onClick={handleClick}>
        Click!
      </button>
    </div>
  );
}



Enter fullscreen mode Exit fullscreen mode

Run the application and see the output:

forward-ref

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 remain the same.



import React, { useRef } from "react";
import Input from "./Input";

export default function CreateRefApiExample() {
//let inputRef = React.createRef();

let inputRef = useRef(null);

const handleClick = () => {
inputRef.current.focus();
};

return (
<div style={{ border: "1px solid red", width: "400px" }}>
<b>Parent Component</b>
<br />
<br />
<Input ref={inputRef} />
<button style={{ margin: "8px" }} onClick={handleClick}>
Click!
</button>
</div>
);
}

Enter fullscreen mode Exit fullscreen mode




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!

Top comments (1)

Collapse
 
ismarcochow profile image
Marco Chow

Brief and Simplicity, thanks.