# The Power of forwardRef in React.js: When and How to Use It

# Introduction

React.js makes it easier to create user interfaces, but it can be difficult to directly access the DOM and component instances. `forwardRef` helps solve this problem by making it simpler to pass and manage references.

# Direct Access Challenges in Component Libraries

Let's say we're developing a `CustomInput` component to expose from our library, intending to let developers control focus or integrate with third-party libraries requiring direct DOM access. A common challenge arises when trying to allow the parent component to directly interact with the `CustomInput`'s underlying DOM node.

Consider the initial approach without `forwardRef`:

```javascript
// CustomInput component without forwardRef
function CustomInput(props) {
  // Attempting direct DOM access
  return <input {...props} />;
}

// Attempting to use ref in a parent component
function ParentComponent() {
  const inputRef = React.createRef();

  // Attempt to focus the input on button click fails
  // because CustomInput doesn't forward the ref
  const focusInput = () => {
    inputRef.current.focus(); // Error: inputRef.current is null
  };

  return (
    <>
      <CustomInput ref={inputRef} />
      <button onClick={focusInput}>Focus the input</button>
    </>
  );
}
```

In this scenario, the parent component's attempt to focus the `CustomInput` fails because `ref` is not automatically passed through. **Older solutions, such as using props to pass down callbacks or using context, make things more complicated and hide the intended direct control features.**

These challenges reveal React's initial refs limitations, emphasizing the need for `forwardRef` to improve component interaction and library usability.

# Introduction of forwardRef

`forwardRef` lets refs be sent to a DOM node or component instance inside a component, making direct interactions easier and helping components work together better.

# How forwardRef Works

`forwardRef` wraps a component, enabling it to receive a `ref` and forward it to a child DOM element or component. This is crucial for operations requiring direct access, like input focus or animation control.

# Practical Example

Using `forwardRef` simplifies focusing on a nested button component:

```javascript
import React, { forwardRef } from 'react';

const FancyButton = forwardRef((props, ref) => (
  <button ref={ref} {...props}>{props.children}</button>
));

// Parent component using FancyButton
const ParentComponent = () => {
  const buttonRef = React.useRef(null);

  const focusButton = () => buttonRef.current.focus();

  return (
    <>
      <FancyButton ref={buttonRef}>Click Me</FancyButton>
      <button onClick={focusButton}>Focus the Fancy Button</button>
    </>
  );
};
```

# Appropriate Use Cases for forwardRef

`forwardRef` is especially helpful for working with direct DOM access, managing focus, animations, and integrating with libraries focused on the DOM.

It often comes in handy for making reusable component libraries that need encapsulation and direct instance access.

However, be careful with overusing refs, as the React [documentation](https://react.dev/reference/react/forwardRef) says:

> **Do not overuse refs.** You should only use refs for *imperative* behaviors that you can’t express as props: for example, scrolling to a node, focusing a node, triggering an animation, selecting text, and so on.
> 
> **If you can express something as a prop, you should not use a ref.** For example, instead of exposing an imperative handle like `{ open, close }` from a `Modal` component, it is better to take `isOpen` as a prop like `<Modal isOpen={isOpen} />`.
