October 16, 2024

useRef: References in React, a better way to manage DOM elements

Spread the love

In a typical React dataflow, props are the only way that parent components interact with their children. To modify a child, you re-render it with new props. However, there are a few cases where you need to imperatively modify a child outside of the typical data flow. The child to be modified could be an instance of a React component, or it could be a DOM element. For both of these cases, React provides an escape hatch.


When to use Refs?

There are a few good use cases for refs:
– Managing focus, text selection, or media playback.
– Triggering imperative animations.
– Integrating with third-party DOM libraries.


What are the arguments?

It takes only one argument and that is the initial value that you want to initialize with.


What does it return?
  • It returns an object with a key of “current” which points to the DOM node.
  • We can then get the value of the element using the “value” key of that object

How to use it?
  • First, we need to import useRef from react
  • Then we can declare a variable using useRef and set the initial value

Using ref for selecting text from an input

One possible solution for selecting the text from an input is to use useState. We could update the state with the target value on every keystroke but we usually only need that value on submitting the form. So instead of useState, we can use ref as follows:

import React, { useRef } from "react";

const RefComponent = () => {
  const emailRef = useRef();

  const submitHandler = (event) => {
    event.preventDefault();
    console.log(emailRef.current.value);
    emailRef.current.value = "";
  };
  return (
    <React.Fragment>
      <form onSubmit={submitHandler}>
        <label>
          E-Mail:
          <input ref={emailRef} type="text" name="email" />
        </label>
        <input type="submit" />
      </form>
    </React.Fragment>
  );
};

export default RefComponent;
  • First we import useRef from react.
  • Then we declare a variable emailRef with an initial value of null using useRef.
  • We then set the ref prop to the variable in our input element, so now our declared variable points to that DOM node.
  • We can then select the value and use it as per our need by simply accessing it using the current and value key of that object.
  • In our example, once we submit the form we console log the input using ref.
  • We usually don’t use ref for setting a value, only to get the value, but if needed we can use it to set a particular value. In our case, let’s say we want to clear the input once the form is submitted. We can then set the value to blank also.

forwarding ref FROM a custom element

In order to use ref in our custom element we just have to make some tweaks to our custom element so that it can accept ref alongside with prop. We will define our custom component as follows:

import React from "react";

const Input = React.forwardRef((props, ref) => {
  return (
    <div>
      <label htmlFor={props.input.id}>{props.label}</label>
      <input ref={ref} {...props.input} />
    </div>
  );
});

export default Input;
  • We wrapped our component with React.forwardRef and passed ref along with prop.
  • This ensures that our custom component now accepts ref and then we can pass that ref to the desired element. In our case, it’s passed to the input element.
  • NOTE:
    • We used object destructuring to pass all the prop inputs to our input element.
    • This is a nice way to make sure that we can pass all the attributes without restricting the user.
  • We can then use ref for our custom element similar to a built in element.

forwarding ref and functions from a custom element

We rarely have a situation like this, but when we do we can easily manage that with the proposed solution.

import React, { useImperativeHandle } from "react";

const Input = React.forwardRef((props, ref) => {
  const logThis = () => {
    console.log("Function inside the custom element");
  };

  useImperativeHandle(ref, () => {
    return {
      insideCustomElement: logThis,
    };
  });

  return (
    <div>
      <label htmlFor={props.input.id}>{props.label}</label>
      <input ref={ref} {...props.input} />
    </div>
  );
});

export default Input;
  • We use yet another hook from react called useImperativeHandle
  • We can call this inside our custom component and pass in ref as the first argument and the second argument is a function which returns an object with a key value pair of the function name and the actual function.
  • We call this function in our component using emailRef.current.insideCustomElement

Hopefully, this clears the use case and how to use Refs in React.
Feel free to check out my portfolio here


Spread the love

One thought on “useRef: References in React, a better way to manage DOM elements

Leave a Reply

Your email address will not be published. Required fields are marked *