Design Converter
Education
Last updated on Feb 27, 2025
•5 mins read
Last updated on Feb 27, 2025
•5 mins read
Software Development Executive - I
He writes code, breaks things, fixes them, and then does it all over again!
How do you manage refs in React?
Do you use useRef in functional components or createRef in class components? Understanding both can help you write better code.
Refs let you access DOM elements and component instances without triggering re-renders.
In this blog, we'll look at React useRef in class component and compare it with useRef in functional components. You’ll learn when to use refs, how they work, and best practices for keeping your code clean and fast.
Figure: High-level flow of ref management in React components.
The useRef hook is a built-in feature in React designed primarily for functional components. It allows you to create a mutable ref object that persists for the entire lifetime of the component. Some key points include:
• Initialization: It takes an initial value as an argument.
• Mutable Object: Returns an object with a current property that can be updated.
• Use Cases: Often used to store DOM element references, mutable values, or to avoid triggering re-renders on value changes.
Example: Using useRef in a Functional Component
1import React, { useRef, useEffect } from 'react'; 2 3function FunctionalComponent() { 4 const inputRef = useRef(null); 5 6 useEffect(() => { 7 // Focus on the input element when the component mounts 8 inputRef.current.focus(); 9 }, []); 10 11 return <input ref={inputRef} type="text" placeholder="Type here..." />; 12} 13 14export default FunctionalComponent;
In class components, the createRef function is used to create refs. Although it serves a similar purpose as useRef, it is considered a legacy approach and is not recommended for new code.
• Initialization: Returns a ref object with a current property initialized to null.
• Usage: Primarily used in class components to access and interact with DOM elements.
• Lifecycle: Refs are attached when the component mounts and can be accessed via instance properties.
Example: Using createRef in a Class Component
1import React, { Component } from 'react'; 2 3class ClassComponent extends Component { 4 constructor(props) { 5 super(props); 6 this.inputRef = React.createRef(); 7 } 8 9 componentDidMount() { 10 // Focus on the input element when the component mounts 11 this.inputRef.current.focus(); 12 } 13 14 render() { 15 return <input ref={this.inputRef} type="text" placeholder="Type here..." />; 16 } 17} 18 19export default ClassComponent;
In class components, attaching a ref to a DOM element is straightforward. By utilizing createRef, you can create a reference in the constructor and then assign it to the desired DOM element via the ref attribute.
Example:
1class MyComponent extends Component { 2 constructor(props) { 3 super(props); 4 this.myRef = React.createRef(); 5 } 6 7 componentDidMount() { 8 // Accessing the DOM element 9 console.log(this.myRef.current); 10 } 11 12 render() { 13 return <div ref={this.myRef}>Hello, World!</div>; 14 } 15}
When working with class components, refs provide a mechanism to:
• Access DOM elements directly.
• Store mutable values that do not affect the rendering cycle.
• Optimize performance by avoiding unnecessary re-renders.
• Non-Visual Data Storage: Use refs to store values that do not impact the UI.
• Imperative Manipulations: They are ideal for scenarios where you need to imperatively modify child components or DOM nodes.
• Performance: Avoid storing values in state that are only used for DOM manipulation.
• Declarative Over Imperative: Always consider if a task can be handled declaratively before opting for refs.
• State Ownership: Ensure that state that impacts rendering is managed properly and not misused via refs.
The useRef hook (or createRef in class components) can store values that don't require a re-render. This is particularly useful for expensive operations that should not run on every render.
Example:
1class ExpensiveOperationComponent extends Component { 2 constructor(props) { 3 super(props); 4 this.cache = React.createRef(); 5 } 6 7 componentDidMount() { 8 // Compute something expensive only once 9 this.cache.current = this.computeExpensiveValue(); 10 } 11 12 computeExpensiveValue() { 13 // Imagine an expensive computation here 14 return 42; 15 } 16 17 render() { 18 return <div>Cached Value: {this.cache.current}</div>; 19 } 20}
For event listeners such as scroll or resize, using refs to store handler functions can prevent them from being recreated on every render, leading to better performance.
Sometimes, you may need a parent component to access a child’s DOM node. Although this breaks encapsulation to some extent, it can be useful for tasks like focusing an input or measuring dimensions. This is typically achieved via ref forwarding.
Example:
1import React, { forwardRef } from 'react'; 2 3const ChildComponent = forwardRef((props, ref) => ( 4 <input ref={ref} type="text" placeholder="Forwarded ref input" /> 5)); 6 7class ParentComponent extends Component { 8 constructor(props) { 9 super(props); 10 this.childInputRef = React.createRef(); 11 } 12 13 componentDidMount() { 14 // Access the child's DOM node 15 this.childInputRef.current.focus(); 16 } 17 18 render() { 19 return <ChildComponent ref={this.childInputRef} />; 20 } 21} 22 23export default ParentComponent;
Understanding React Element ID helps you manage components better. But relying on static IDs can cause issues. Using refs gives you more control over the DOM and improves state handling. This approach keeps your React applications easy to manage and scale.
Tired of manually designing screens, coding on weekends, and technical debt? Let DhiWise handle it for you!
You can build an e-commerce store, healthcare app, portfolio, blogging website, social media or admin panel right away. Use our library of 40+ pre-built free templates to create your first application using DhiWise.