useRef Hook in React
In React, we often wish to track the frequent changes in a component without triggering re-renders. Even though the useState and useReducer hooks help control a component's local state, making too many calls may cause the component to be re-rendered.However, we have a React useRef hook to resolve these problems.
What is UseRef Hook in React?
Ref signifies reference, which implies that it can refer to anything, including DOM nodes.
useRef in react returns a mutable reference object that doesn't trigger re-rendering of the component when they change and persist throughout their lifetimes. This object has a current property that holds a mutable value.
useRef React hook allows us to create a reference to a DOM element and keep track of variables without causing re-renders.
Here, the initialValue is the value of the current property of the ref object initially. It can be of any type.
- The useRef React hook allows us to save values between renders.
- It stores a mutable value that does not cause a re-render when updated.
- It helps us to access a DOM element directly.
Since useRef is a React hook, we can employ it for functional components. We have createRef, which allows us to use refs in class-based components.
Let us understand how to use the useRef React hook.
How to Use React UseRef Hook ?
To use the react useRef hook :
Import useRef from react.
Declare one or more refs, and call useRef at the top level of your component.
Set the ref value by accessing the .current property of the reference object.
Access the ref value.
export default App
We can use the useRef React hook for a variety of purposes like :
- Accessing and manipulating the DOM elements.
- Referencing a value with a ref and tracking the state changes.
- To keep mutable values.
In the later sections of the article, we will explore these use cases in greater detail.
Re-rendering a Component Using useState
In React applications, the useState() hook re-renders the components when their state changes. However, there are instances where we need to track state changes without triggering re-renders.
Initially, a component is rendered with the undiluted state values when any change is yet to trigger. A component re-renders when :
- Local state updates.
- The props change.
These changes call the render method to incorporate them and update the application. This triggers the re-rendering of a component each time the state updates. On the other hand, by using a useRef, our component will render only once.
Accessing DOM Elements
In React, we do not need to manipulate the DOM often because it updates automatically to match our render output. Sometimes, though, we might need the DOM element, for example, to focus on an element and scroll to it.
The React useRef hook enables us to handle the DOM manipulations. We can directly access DOM elements by adding a ref attribute to an element.
Let us understand this concept with the following example :
In this example, we will use the useRef in react hook to bring the text field into focus.
- To access a DOM node, we will import the useRef Hook.
- Then, declare a ref inside the component and pass it to the DOM element as the ref attribute.
- useRef returns an object having a property, i.e., current.
- The initial value of inputText.current is null.
- React will put a reference to the DOM element into inputText.current, which we can access through an event handler.
Tracking State Changes
The useRef in react keeps track of previous state values since we can persist useRef values between renders.
We will use a combination of useState, useEffect, and useRef to track the previous state of an input text. With the useEffect hook, we update the useRef value every time the input text changes.
How Values are Stored in useRef?
A unique way to implement a React useRef hook is to use it to store values instead of DOM references. Either these values could be a state that may not be necessary to update often or one that can be updated as frequently as possible without re-rendering the component.
A ref is a mutable object, but its value persists across re-renders. The DOM element may change when a component is re-rendered; if this happens, the reference to the DOM element should either change or be maintained to avoid inconsistencies in the final rendering.
How to Keep a Mutable Variable?
As the name implies, mutable variables contain mutable values, i.e., the values of the variables are alterable within the same memory space during their creation.Since userRef in react returns a reference object with a single property, current, we know that this reference object is mutable.
Let us understand how to deal with a mutable variable :
There are two ways of keeping data between the re-renders for the class-based and functional components.
In Class Components
- In the component state :
The component is re-rendered with the state change.
- In an instance variable :
An instance variable persists through the lifetime of a component, so there is no re-render when it changes.
In Functional Components
- In a state variable :
The component is re-rendered with updates in the state variable.
- In a ref :
There are no re-renders while mutating the .current property.
Below is an example of keeping a mutable variable in a ref.
In this example, we will console log the number of times we press the button.
- We will declare a ref, countClick, with an initial value of 0.
- This reference object stores the number of times a button is clicked.
- The reference value gets updated and logged to the console as we click the button.
As you may have noticed in your console, "Component is rendered" is only logged once, implying that button clicks or changes in the reference value do not cause component re-rendering.
How to Update a Ref?
We can assign the new value to .current to update the useRef variable.
Since we are updating the refs during rendering, the above example causes unexpected behavior. React may restart the "Render phase", so it must be pure, there can be no side effects.
Is Updating a Ref a Side Effect?
Ref updates are side effects that should happen in the layout or commit phase of react, so we should handle them inside a useEffect or an event handler.
To avoid undesired output, we will use the useEffect hook in the previous example :
- The useRef react hook allows us to create a reference to a DOM element and keep track of variables without causing re-renders.
- It returns a mutable object that doesn’t cause component re-renders when they change and persist throughout their lifetimes. This object has a current property that holds a mutable value.
- We can access the reference to the element through the .current property. We can assign the new value to .current to update the useRef() variable.
- The useRef() in react hook keeps track of previous state values since we can persist useRef() values between renders.
- Updating a ref is a side effect that should happen in the layout or commit phase. Therefore, we should handle them inside a useEffect or an event handler.