Clean β’ Professional
In React, sometimes you need to access a child componentβs DOM node directly β for example, to focus an input field, trigger animations, or measure its size. Normally, props only allow passing data, not references to DOM nodes. This is where React Forward Ref comes in handy.
React Forward Ref allows you to pass a ref from a parent component to a child component, giving the parent direct access to the childβs DOM element.
React.forwardRef is a React API that lets function components accept a ref from their parent. By default, function components donβt support ref like class components do.
Benefits:
Syntax:
const Child = React.forwardRef((props, ref) => {
return <input ref={ref} {...props} />;
});
props β Normal props passed from parentref β Forwarded reference from the parent componentExample: Focusing an Input Field
import React, { useRef } from "react";
const InputField = React.forwardRef((props, ref) => {
return <input ref={ref} placeholder="Type here..." />;
});
function App() {
const inputRef = useRef(null);
const focusInput = () => {
inputRef.current.focus(); // Focus the input field
};
return (
<div>
<h1>React Forward Ref Example</h1>
<InputField ref={inputRef} />
<button onClick={focusInput}>Focus Input</button>
</div>
);
}
export default App;
InputField is a functional component wrapped in React.forwardRef.inputRef in the parent (App) points directly to the <input> element inside the child.Class components naturally support refs:
class InputField extends React.Component {
render() {
return <input ref={this.props.forwardedRef} placeholder="Class input" />;
}
}
const ForwardedInput = React.forwardRef((props, ref) => {
return <InputField {...props} forwardedRef={ref} />;
});
You can combine forwardRef with hooks like useImperativeHandle to expose specific methods to the parent.
import React, { useRef, forwardRef, useImperativeHandle } from "react";
const Child = forwardRef((props, ref) => {
const localRef = useRef();
useImperativeHandle(ref, () => ({
focus: () => {
localRef.current.focus();
},
}));
return <input ref={localRef} placeholder="Controlled by parent" />;
});
function App() {
const childRef = useRef();
return (
<div>
<Child ref={childRef} />
<button onClick={() => childRef.current.focus()}>Focus Child Input</button>
</div>
);
}
export default App;
useImperativeHandle allows you to customize what is exposed to the parent via the ref.childRef.current.focus() without directly accessing the DOM node.