Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React.forwardRef is already possible without it, so what's the use of it?

I'm confused on the point of React.forwardRef. As explained in its documentation, I understand that its main use is for a Parent Component to gain access to DOM elements of the Child Component. But I can already do that without even having to use it.

Here is a code example that you can plug into CodeSandbox and see that it works:

import React, {useRef, useEffect} from "react";
import "./styles.css";

const ChildComponent = (props) => {

  useEffect( ()=> {
    props.callbackFunction()
  })

  return(
    <div ref={props.fRef}>
      {"hello"}
    </div>
  )
}


export default function App() {
  const callbackFunction = () => {
    console.log("The parent is now holding the forwarded ref to the child div: ")
    console.log(forwardedRef)
  }

  const forwardedRef = useRef(null)

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <ChildComponent name="gravy" callbackFunction={callbackFunction} fRef={forwardedRef}/>
    </div>
  );
}

Or here's the embed of this example. Honestly, I'm kind of new to this and I don't know exactly how embeds work and whether someone fiddling with the embed changes my original Sandbox or not, so I was hesitant to put it. But here it is. Example Forwarding Ref

In the example, the parent App() component successfully passes a ref to the child which the child attaches to its rendered div. After it renders, it calls a callback function to the parent. The parent then does a console log where it proves that its forwarded ref now has a hold of the child's div. And this is all done without React.forwardRef.

So what then is the use for React.forwardRef?

like image 360
Jordy Avatar asked Mar 31 '20 23:03

Jordy


People also ask

Why do we need forwardRef reaction?

The forwardRef method in React allows parent components to move down (or “forward”) refs to their children. ForwardRef gives a child component a reference to a DOM entity created by its parent component in React. This helps the child to read and modify the element from any location where it is used.

How do you use forwardRef in React?

The only way to pass a ref to a function component is using forwardRef. When using forwardRef, you can simply pass the ref to a DOM element, so the parent can access it like in example 1, or you could create an object with fields and methods using the useImperativeHandle hook, which would be similar to eample 2.

What is React ref used for?

Refs are a function provided by React to access the DOM element and the React element that you might have created on your own. They are used in cases where we want to change the value of a child component, without making use of props and all.

Is React forwardRef a hoc?

forwardRef() which means we have to apply the HOC before React.


2 Answers

You're absolutely right that you can do what you've described. The downside is that you're forced to expose an API (ie: the fRef prop) for it to work. Not a huge deal if you're a solo developer building an app, but it can be more problematic eg. if you're maintaining an open-source library with a public API.

In that case, consumers of the library won't have access to the internals of a component, meaning you'd have to expose it for them somehow. You could simply do what you're suggesting in your example and add a named prop. In fact, that's what libraries did before React 16.3. Not a huge deal, but you'd have to document it so people know how to use it. Ideally, you'd also want some kind of standard that everyone used so it wasn't confusing (many libraries used the innerRef naming convention), but there'd have to be some consensus around that. So all doable, but perhaps not the ideal solution.

Using forwardRef, passing a ref to a component just works as expected. The ref prop is already standardized in React, so you don't need to go look at docs to figure out how to pass the ref down or how it works. However, the approach you describe is totally fine and if it meets your needs, by all means go with that.

like image 188
ericgio Avatar answered Sep 21 '22 11:09

ericgio


As mentioned in the docs , it's useful for highly reusable components, meaning components that tend to be used like regular HTML DOM elements.

This is useful for component libraries where you have lots of "leaf" components. You've probably used one like Material UI.

Example:

Let's say you're maintaining a component library.

You create a <Button/> and <Input/> component that maybe just adds some default styling.

Notice how these components literally are just like regular HTML DOM elements with extra steps.

If these components were made to be used like regular HTML DOM elements, then I expect all the props to be the same, including ref, no?

Wouldn't it be tedious if to get the button ref from your <Button/> component I'd have to get it through something like fRef or buttonRef ?

Same with your <Input/>, do I have to go to the documentation just to find out what ref to use and it's something like inputRef ? Now I have to memorize?

Getting the ref should be as simple as <Button ref={}/>

Problem

As you might know, ref will not get passed through props because, like key, it is handled differently by React.

Solution

React.forwardRef() solves this so I can use <Button ref={}/> or <Input ref={}/>.

like image 26
Abe Caymo Avatar answered Sep 24 '22 11:09

Abe Caymo