DEV Community

loading...
Cover image for Forwarding Refs

Forwarding Refs

Sreashi Saha
Passionate about Web Development and have a keen interest in learning new technologies.
Updated on ・3 min read

Forwarding Refs is a Technique in React. Do you know what is Ref in react?? 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. Now come to ref forwarding,

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.

Syntax:

React.forwardRef((props, ref) => {})

Parameter: It takes a function with props and ref arguments.

Return Value: This function returns a JSX Element.

How Forwarding Refs works??

Ref forwarding is an opt-in feature that lets some components take a ref they receive, and pass it further down (in other words, “forward” it) to a child.

ref argument only exists when you define a component with React.forwardRef call. Regular function or class components don’t receive the ref argument, and ref is not available in props either. Ref forwarding is not limited to DOM components. You can forward refs to class component instances.

const MagicButton = React.forwardRef((props, ref) => (
   <button ref={ref} className="MagicButton">
    {props.children}
   </button>
  ));
  const ref = React.createRef();
  <MagicButton ref={ref}>Click me!</MagicButton>;
Enter fullscreen mode Exit fullscreen mode

So, let's try to understand how things are working in the above example...

*Here we are calling React.createRef for creating React ref and assign it to a ref variable.

*Passing our ref down to
<MagicButton ref={ref}> and forwarding this ref down to <button ref={ref}> by specifying it as a JSX attribute.

*If ref is attached ref.current will point to the <button> DOM node.

How Forwarding Refs is used in HOCs(Higher Order Components)?

A higher Order component is a function that takes a component and returns a new component. Forwarding Refs is also useful for higher-order components.

Let's start with an example and see how exactly everything works.

function logProps(WrappedComponent) {
  class LogProps extends React.Component {
    componentDidUpdate(prevProps) {
      console.log('old props:', prevProps);
      console.log('new props:', this.props);
    }
   render() {
      return <WrappedComponent {...this.props} /> ;
    }
  }

  return LogProps;
}
Enter fullscreen mode Exit fullscreen mode

here the logProps HOC passes all props through to the component it wraps, so the rendered output will be the same.

class MagicButton extends React.Component {
  focus() {
    // ...
  }

  // ...
}
export default logProps(MagicButton);
Enter fullscreen mode Exit fullscreen mode

refs will not get passed through. That’s because ref is not a prop. Like key, it’s handled differently by React. If you add a ref to a HOC, the ref will refer to the outermost container component, not the wrapped component.

So in this case, MagicButton component will actually be attached to the LogProps component:

import MagicButton from './MagicButton';
const ref = React.createRef();
<MagicButton
  label="Click Me"
  handleClick={handleClick}
  ref={ref}
/>;
Enter fullscreen mode Exit fullscreen mode

we can explicitly forward refs to the inner MagicButton component using the React. forwardRef API. React. forwardRef accepts a render function that receives props and ref parameters and returns a React node. See in the example below

function logProps(Component) {
  class LogProps extends React.Component {
    componentDidUpdate(prevProps) {
      console.log('old props:', prevProps);
      console.log('new props:', this.props);
    }

    render() {
      const {forwardedRef, ...rest} = this.props;

      return <Component ref={forwardedRef} {...rest} />;
    }
  }
return React.forwardRef((props, ref) => {
    return <LogProps {...props} forwardedRef={ref} />;
  });
}
Enter fullscreen mode Exit fullscreen mode

Do you know we can even display a Custom name in DevTools?

React.forwardRef accepts a render function. React DevTools uses this function to determine what to display for the ref forwarding component.

If you name the render function, DevTools will also include its name. You can even set the function’s displayName property to include the component you’re wrapping:

function logProps(Component) {
  class LogProps extends React.Component {
    // ...
  }
function forwardRef(props, ref) {
    return <LogProps {...props} forwardedRef={ref} />;
  }
  const name = Component.displayName || Component.name;
  forwardRef.displayName = logProps(${name});
 return React.forwardRef(forwardRef);
}
Enter fullscreen mode Exit fullscreen mode

Hopefully, forwardRef is a bit clear by now. If any queries regarding this write them down in the comment below. Thank you for your time and I hoped my blog is helpful for you.

Happy Learning!!!

Discussion (7)

Collapse
vishal2369 profile image
Vishal2369 • Edited

It is Great, but some codes are not highlighted which makes it little hard to follow.
Also u can add syntax highlighting in your code.
check :- dev.to/jmhungdev/javascript-syntax...

Collapse
sreashi profile image
Sreashi Saha Author • Edited

Yes Previously I tried to do that but had face some issues with that but the link is really helpful Thank you..

Collapse
chococoin profile image
Germán Lugo • Edited

FancyButton>Click me!</MagicButton

It looks weird... it's the right syntax?

Collapse
sreashi profile image
Sreashi Saha Author

Pardon me for my mistakes..I made the changes..thank you ☺️

Collapse
devdanilov profile image
Nik Danilov

The code snippets are very similar to what is published in the React documentation:
reactjs.org/docs/forwarding-refs.html

Please update your examples to avoid plagiarism.

Collapse
imdhanush profile image
Dhanush

Hey, just wanted to know. Same can be done with useRef also right ?

Collapse
sreashi profile image
Sreashi Saha Author

Actually not really..they both are hooks but forwardRef hooks allows React users to pass refs to child components and the ref can be created and referenced with useRef or createRef and then passed in a parent component. Using forwardRef instead of useRef is useful when a ref needs to be accessed in a parent component.
Thank you hope it's helpful ☺️