DEV Community

Cover image for React Refs: Key to DOM Manipulation
Naresh
Naresh

Posted on • Edited on

React Refs: Key to DOM Manipulation

React is a declarative UI library. A declarative? What does that mean? Let's understand the difference between imperative and declarative regarding web applications.

Let's say we wanted to create a page with a button and whenever the user types we should update the value in the Paragraph below the button.

In Imperative UI Programming:

  1. Create a variable to store the value of the count and assign it to 0
  2. Get the button element by id
  3. Get the Paragraph element by id
  4. Create an on-click handler and set it as the button on-click event listener
  5. In on-click handler
    1. update the count value by 1
    2. update the paragraph element textContent with the updated count.
let count = 0;
const button = document.getElementById('button');
const paragraph = document.getElementById('paragraph');

button.onclick = function() {
  count++;
  paragraph.textContent = `Count is : ${count}`;
};

paragraph.textContent = `Count is : ${count}`;
Enter fullscreen mode Exit fullscreen mode

As we can see, we are kind of instructing step by step and we are accessing the DOM elements and modifying them on our own. This can be tedious in big projects. What if we, forget to update the text content of the paragraph after we update the count?

Declarative UI Programming (Using React ):

  1. Create a state variable named count
  2. Create a handler to update the count
  3. Show the count in the paragraph
import { useState } from "react";

export default function App() {
  const [count, setCount] = useState(0);

  const handleCount = () => {
    setCount(count + 1);
  };

  return (
    <div>
      <button onClick={handleCount}>Increment</button>
      <p>{`Count is : ${count}`}</p>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

In the above react program, we didn’t modify any of the DOM elements directly. We just used the API Provided by the JSX syntax, and React will take care of DOM manipulations for us.

To Summarize,

  1. In imperative programming, we instruct the computer on how to perform each step of a task. We directly manipulate the DOM elements and update their values. It involves explicit instructions and control flow to achieve the desired outcome.

  2. In declarative programming, we describe what we want to achieve without specifying the step-by-step instructions. We rely on abstractions and let the framework or library handle the implementation details. In the case of React, we define the desired UI structure and let React take care of updating the DOM based on the state changes.

For more info checkout officail React Docs Declarative UI

So, we don’t get access to the DOM elements directly in React. What if we want to access the DOM elements? This is well handled in React, for this we have refs.

What is Ref?

In React, a Ref is a state variable that will persist values between renders. This is a special kind of state variable as it doesn’t trigger re-render when we update.

We can create a Ref using useRef or createRef. We usually use useRef in functional Components and the createRef in class Components. In this blog, we will use useRef .

As we know react is a Declarative UI library, there is no way we can directly modify the DOM. To give access to DOM elements, React accepts a special property named ref on every component.

This property accepts the ref value and assigns the DOM element as the current value of the ref object we passed.

Syntax:

const countRef = useRef(0); // returns {current:0}
Enter fullscreen mode Exit fullscreen mode

useRef accepts an initial value and returns a mutable object with the current property. This current property will hold the value.

When to Use

  1. Storing timer’s Id
  2. Storing DOM elements
  3. Store any value, that is not needed to trigger a re-render.

When Not to Use

  • NEVER EVER USE Refs inside a component render. This can cause unexpected results.

Ex: let's say we have a ref name countRef and a state with color. When we update the count we will not see the updated value.
But when we change the color value it will show the latest value stored in the ref. So better we don’t use refs in the render.

DOM Manipulation using Refs.

To access the DOM elements created by React, we can use the ref property on the components. If we set this prop, react will assign the DOM element to the current value of the ref.

export const MyComponent = ()=>{
    const inpRef = useRef(null); // creating a ref

    return <input ref={inputRef} /> // passing the ref as an argument, so that react will add the DOM
}
Enter fullscreen mode Exit fullscreen mode

One day, your PO came to you and asked, can we implement scroll-to-top and scroll-to-bottom functionality on the home page. So we can scroll to the top/bottom whenever the user clicks on a button.

To achieve this we will create two buttons in the navigation bar, and when the user clicks on the button we will scroll to the top or bottom. We can do this by invoking the scrollTo function on the element. Let’s see this in action

We will create a ref, that will be used to store the scrollable container DOM element, and we will create two handler functions named

  1. handleScrollToBottom
  2. handleScrollToTop

These two functions will call the scrollTo event on the DOM element. We will pass our container Ref as a parameter to the div element that contains the text.

In the above code, we set the ref property of the div to containerRef. Whenever react sees the ref property, it will assign the DOM element to that ref’s current value.

Now we have access to the DOM element. Whenever the user clicks on those buttons we will directly modify invoke scroll to on the Text Container DOM element.

For more info check out official : React Docs

This is to access the DOM elements in the component, What if we want to access the DOM elements of another Component? We can get access to other components DOM elements using forwardRef.

Let’s Discuss more about forwardRefs and how to expose limited access to DOM elements in the next Post.

Thank you and please provide your feedback.

Top comments (0)