Stop using forwardRef() in your custom components in React
In React, forwardRef lets your component expose a DOM node to parent component with a ref.
To let your component receive a ref and forward it to a child component, we call forwardRef()
.
import { forwardRef } from 'react';
const MyInput = forwardRef(function MyInput(props, ref){
return {...}
})
forwardRef
accepts a render function as an argument. React calls this function with props and ref:
const MyInput = forwardRef(function MyInput(props, ref){
return (
<div>
<label>{props.label}</label>
<input ref={ref}>
</div>
)
})
forwardRef returns a React component that you can render in JSX. Unlike React components defined as plain functions, the component returned by
forwardRef is able to take a ref
prop.
By default, each component’s DOM nodes are private. However, sometimes it’s useful to expose a DOM node to the parent—for example, to allow
focusing it. ref
can be an object or a function, its default value is null
.
Passing ref without using forwardRef
Now the question is, why do we have to wrap custom component with forwardRef
to receive a ref
prop in the component, can't just ref just be a prop?
Simply rename ref
prop to something else,like inputRef
in our example:
function MyInput(props) {
const { inputRef, label, ...otherProps } = props
return (
<div>
<label>{label}</label>
<input {...otherProps} ref={inputRef} />
</div>
)
}
Now in our <Form />
component:
import { useRef } from 'react'
function Form() {
const inputRef = useRef(null)
return (
<form>
<MyInput label="Enter your name:" inputRef={inputRef} />
<button type="button" onClick={handleClick}>
Submit
</button>
</form>
)
}
That's all we have do to get rid of using forwardRef()
from our codebase and life too :p. Is there any benefit associated with using forwardRef()
?
NO! A ref
is an object, passing it through a custom component shouldn't be anything special.
In fact, Andrew Clark (Reactjs core team member), responded to a question (why does forwardRef() exit? Why can't just be a prop?) on X (still Twitter):
That is the eventual plan, but it’s a breaking change so to minimize churn we’re going to group it together with other JSX-related breaking changes we have planned, like removing defaultProps. forwardRef was the stepping stone solution when we introduced hooks. The time is nigh.
In the future, passing a ref as a prop will just work
and forwardRef
will no longer be required. Let's look forward to React19!!!