In React, refs are used to access DOM nodes or React elements created in the render method. One common utilization of refs is focusing on input elements. However, passing refs between components isn’t straightforward, which is where forwardRef
comes into play.
Understanding the Basics
forwardRef
is a React method used to pass a ref through a component to one of its children. This is extremely useful when you need a reference to a DOM node for something like focusing on an input field. However, the usage of forwardRef
can sometimes be confusing, especially when distinguishing between different use cases.
Exploring Use Cases
Case 1: Direct Ref Passing
In the first scenario, a ref is created in a parent component using useRef
. This ref is then passed to a child component via a prop. The child component, defined using forwardRef
, receives this ref and attaches it to a DOM node:
// App.js
import { useRef } from 'react'; import MyInput from './MyInput.js'; export default function Form() { const ref = useRef(null); function handleClick() { ref.current.focus(); } return ( <form> <MyInput label="Enter your name:" ref={ref} /> <button type="button" onClick={handleClick}> Edit </button> </form> ); }
// MyInput.js
import { forwardRef } from 'react'; const MyInput = forwardRef(function MyInput(props, ref) { const { label, ...otherProps } = props; return ( <label> {label} <input {...otherProps} ref={ref} /> </label> ); }); export default MyInput;
In this case, the ref created in Form
is passed to MyInput
, which then forwards it to the input
element. This allows the handleClick
function in Form
to focus the input
element in MyInput
.
Case 2: Optional Ref Passing
In the second scenario, the child component is also defined using forwardRef
, but the parent doesn’t pass a ref. This is a valid case since React components will ignore props they don’t use, and the ref
prop will just be undefined
if not provided:
// chat.js
import { Input } from './ui/input' <Input value={previewTokenInput} placeholder="OpenAI API key" onChange={e => setPreviewTokenInput(e.target.value)} />
The Input
component is structured to forward refs to the input
element but in this instance, no ref is passed from the parent component. This doesn’t cause any issues; it simply means that the ref
prop in Input
will be undefined
.
Conclusion
The forwardRef
function in React provides a way to pass refs through components to child elements, which is a common requirement in many React applications. Whether or not a parent component passes a ref, the child component can be structured using forwardRef
to handle refs correctly. This flexibility allows for a variety of component structures while ensuring refs are handled in a consistent and predictable manner.