DEV Community

loading...

How to use React forwardRef

renatobentorocha profile image Renato Rocha ・2 min read

When we are creating a React application, some times, we need access properties of a Element created through jsx. As an example, a simple case where we want to set focus on a input text. In this case we can do that using the React hook useRef in a straight away.

import React, { useRef, useEffect } from "react";

function App() {
  const inputRef = useRef(null);

  useEffect(() => {
    inputRef.current.focus();
    console.log({ inputRef });

    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return (
    <div>
      <input type="text" ref={inputRef} style={style} />
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

The useRef hook returns an object that contains a reference to the corresponding DOM node whenever that node changes.

However, what if we are using a pretty cool Input Component from a third party and go along with the same way, using the useRef hook?

import React from "react";

const Input = () => <input type="text" style={style} />;

export default Input;
Enter fullscreen mode Exit fullscreen mode
import React, { useRef, useEffect } from "react";
import Input from "./Input";

function App() {
  const inputRef = useRef(null);

  useEffect(() => {
    if (inputRef.current) {
      inputRef.current.focus();
    }

    console.log({ inputRef });

    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return (
    <div>
      <Input ref={inputRef} />
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

So we will receive the warning message and also can see that the reference to Input Component is null:

In this case, the error was because the Input Component is a children of App component and the "ref" cannot pass from App Component to Input. On this case, we need to change the Input Component to use the forwardRef.

import React, { forwardRef } from "react";

const Input = (props, ref) => <input ref={ref} type="text" style={style} />;

export default forwardRef(Input);
Enter fullscreen mode Exit fullscreen mode

And another example where we may need to use forwardRef is in conjunction with the High Order components.

Discussion (6)

pic
Editor guide
Collapse
z2lai profile image
z2lai • Edited

I've implemented my ref forwarding with useRef hook and function components the same way you did, but I'm still getting inputRef.current is undefined and the warning "Function components cannot be given refs."

According to React docs, you need to implement ref forwarding using the useImperativeHandle hook: reactjs.org/docs/hooks-reference.h...

Collapse
renatobentorocha profile image
Renato Rocha Author

Hello z2lai, thanks by comment.

I implemented the example in this post for you to see: github.com/renatobentorocha/forwar....

The useRef hook is used to persist an object reference even after a component to be rerendered: reactjs.org/docs/hooks-reference.h...

Collapse
z2lai profile image
z2lai

Hey Renato, thanks so much for the response! Your example convinced me that there was something else that was wrong in my app. It turns out that my "forwardRef(Input);" was wrapped in another HOC that was not passing in ref as the extra second argument. So I removed the HOC and now it works, thanks a lot for your help!

Collapse
joshio58 profile image
Joshua Burke

Dude you should be writing the react docs. Thanks Bro!

Collapse
codefinity profile image
Manav Misra

Exactly what I was looking 👀 4. Tx.

Other write ups are using class 👎🏾 or just have the <input> in the same component (like you started with).

Collapse
karannp profile image
Karan Nagpal

This was very helpful, Thanks a ton!!