![]()
In React, refs (short for references) provide a way to directly access and interact with DOM elements or class components within a functional or class-based component. Refs are commonly used when you need to interact with DOM elements directly or trigger imperative code in your React components, such as focusing an input, measuring an element’s dimensions, or managing animations.
1. What are Refs in React?
In React, a ref is a special object that allows you to reference a DOM node or a React component instance directly. You can create a ref using React.createRef() in class components or the useRef() hook in functional components.
1.1 Using Refs in Class Components
In class components, refs are created using React.createRef():
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myInputRef = React.createRef();
}
focusInput = () => {
this.myInputRef.current.focus(); // Accessing DOM element directly
};
render() {
return (
<div>
<input ref={this.myInputRef} type="text" />
<button onClick={this.focusInput}>Focus Input</button>
</div>
);
}
}
In this example:
this.myInputRefis a reference to the input element.this.myInputRef.currentprovides access to the actual DOM node, allowing thefocusInputmethod to focus the input field when the button is clicked.
1.2 Using Refs in Functional Components (with useRef)
In functional components, we use the useRef hook to create refs:
import React, { useRef } from 'react';
const MyComponent = () => {
const myInputRef = useRef(null);
const focusInput = () => {
myInputRef.current.focus(); // Accessing DOM element directly
};
return (
<div>
<input ref={myInputRef} type="text" />
<button onClick={focusInput}>Focus Input</button>
</div>
);
};
export default MyComponent;
In this example:
useRefis used to create a reference to the input element.myInputRef.currentgives us access to the DOM element to call.focus()on it.
2. Forwarding Refs in React
Sometimes, you might need to forward refs from one component to another, especially if you’re building higher-order components (HOCs) or reusable components. React provides a mechanism called forward refs using React.forwardRef() to allow refs to be passed down to child components.
2.1 What is React.forwardRef?
React.forwardRef is a higher-order function that allows a component to receive a ref from its parent and then forward it to one of its child components. This is useful when you want to create a reusable component that can still interact with the DOM via refs.
3. Using React.forwardRef
Let’s see an example of how to use React.forwardRef to forward a ref to a child component:
3.1 Example: Forwarding Refs to a DOM Element
import React, { useRef } from 'react';
// This is a functional component that accepts a ref.
const CustomInput = React.forwardRef((props, ref) => {
return <input ref={ref} {...props} />;
});
const ParentComponent = () => {
const inputRef = useRef(null);
const focusInput = () => {
inputRef.current.focus(); // Focus the input element in CustomInput
};
return (
<div>
<CustomInput ref={inputRef} type="text" />
<button onClick={focusInput}>Focus Input</button>
</div>
);
};
export default ParentComponent;
In this example:
- The
CustomInputcomponent is wrapped withReact.forwardRef. - The
refis forwarded to the<input />element inside theCustomInputcomponent. - In
ParentComponent, we create a ref (inputRef) and pass it toCustomInput. - The button in
ParentComponentfocuses the input element via the forwarded ref.
4. How React.forwardRef Works
- When you use
React.forwardRef, React automatically passes therefas the second argument to the component. - This allows the child component to directly attach the
refto one of its DOM elements or a class component.
4.1 Syntax of React.forwardRef
const MyComponent = React.forwardRef((props, ref) => {
// ref is forwarded to the DOM element inside the component
return <div ref={ref}>{props.children}</div>;
});
propscontains the props passed to the component.refis the forwarded reference that can be attached to a DOM element or class component.
5. Practical Use Cases of Forwarding Refs
5.1 Forwarding Refs in Reusable Components
When you create reusable components like buttons, inputs, or modals, it might be useful to forward refs so that the parent component can interact with those elements directly.
Example:
// Reusable Button component
const Button = React.forwardRef((props, ref) => (
<button ref={ref} {...props}>
{props.children}
</button>
));
// Parent Component
const ParentComponent = () => {
const buttonRef = useRef(null);
const handleClick = () => {
buttonRef.current.click(); // Imperatively trigger button click
};
return (
<div>
<Button ref={buttonRef}>Click Me</Button>
<button onClick={handleClick}>Trigger Button Click</button>
</div>
);
};
In this case, the Button component forwards its ref to the <button> element, allowing the parent to trigger the button’s click event programmatically.
6. Combining Refs and Forwarding Refs in Higher-Order Components (HOCs)
Another common scenario where forwardRef is used is in higher-order components (HOCs), where a component is wrapped around another component, and you still want to be able to forward the ref to the wrapped component.
Example:
const withForwardedRef = (Component) => {
return React.forwardRef((props, ref) => {
return <Component {...props} forwardedRef={ref} />;
});
};
const ButtonWithRef = withForwardedRef((props, ref) => {
return <button ref={ref} {...props}>{props.children}</button>;
});
const ParentComponent = () => {
const buttonRef = useRef(null);
return (
<div>
<ButtonWithRef ref={buttonRef}>Click Me</ButtonWithRef>
</div>
);
};
In this case:
withForwardedRefis a higher-order component that wraps aButtoncomponent and forwards its ref.- The ref is passed down from
ParentComponentto theButtoncomponent usingReact.forwardRef.
7. Best Practices and Considerations
- Use
forwardRefsparingly: It’s best to useforwardRefonly when absolutely necessary. Overuse can make the code harder to understand. - Ref Usage: Refs should be used for imperative code (e.g., focus management, animations, accessing DOM elements), not for managing state or rendering.
- Functional Components: Prefer functional components with hooks like
useRefanduseImperativeHandlefor modern React code.
