Using ref in react

In react, there are many ways to interact with browser DOM. For example, input fields data or value is a part of browser DOM as well. In a react project, react has the control over it so that we don’t have to work with the heavy lifting things. One of the primary use cases of ref is with the input fields and values.

In this article, we will learn about the ref and how to work with it. Below is the topic that we will cover,

  • Creating form,
  • Using ref
  • Controlled and uncontrolled input

Creating form

  • Create a form with some input fields in it in a react project.

In the App.js file,

import React, { Fragment, useState } from "react";
import AddUser from "./AddUser";
import './App.css'
import SimpleInputForm from "./components/SimpleInputForm";
const App = () => {
  return (
    <Fragment>
      <SimpleInputForm />
    </Fragment>
  );
}

export default App

In the SimpleInputForm.js file,

import React from "react";

const SimpleInputForm = () => {
  return (
    <div className="w-2/3 mx-auto">
      <form class="card-body my-20 p-0">
        <div className="form-control items-center lg:items-start">
          <input
            type="text"
            placeholder="user name"
            className="input input-bordered w-full max-w-md "
          />
        </div>
        <div className="form-control items-center lg:items-start">
          <input
            type="email"
            placeholder="email"
            className="input input-bordered w-full max-w-md "
          />
        </div>
        <div className="form-control items-center lg:items-start mt-6">
          <button type="submit" className="btn btn-sm w-full max-w-md">
            Register
          </button>
        </div>
      </form>
    </div>
  );
};

export default SimpleInputForm;

Note: Please read this article to know about Creating a react project with tailwind CSS and this one to Create an input form in react.

Using ref

Ref is for reference. React gives us many hooks to use and manipulate the user interface as our will. One of them is useRef(). With this, we can take a reference of an exact browser node. For example, an input field.

  • Import useRef() hook from react in the SimpleInputForm component.
import React, { useRef } from "react";
  • Create to reference variable for name and input field inside the component function.
// reference variable for name
const enteredNameRef = useRef();
// reference variable for email
const enteredEmailRef = useRef();

By default, the value of each reference will be undefined.

  • Declare the ref attribute to each of the input fields and pass their respective reference variable to them as value.
<div className="form-control items-center lg:items-start">
  <input
    ref={enteredNameRef}
    type="text"
    placeholder="user name"
    className="input input-bordered w-full max-w-md "
  />
</div>
<div className="form-control items-center lg:items-start">
  <input
    ref={enteredEmailRef}
    type="email"
    placeholder="email"
    className="input input-bordered w-full max-w-md "
  />
</div>

Now that the reference variables are being used in the input fields, these will return an object. That object will contain some node materials for their respective field. We need to use the current method from the object. And inside the current, we will get the value. On that value, we will get the values that will be written in the input fields.

//   getting values for name and email from the reference
const enteredName = enteredEmailRef.current.value;
const enteredEmail = enteredEmailRef.current.value;
  • Create an onSubmit() event and a function for the form,
//   form handling function
const handleFormSubmission = (e) => {
  e.preventDefault();
};
<div className="w-2/3 mx-auto">
  <form onSubmit={handleFormSubmission} class="card-body my-20 p-0">
    <div className="form-control items-center lg:items-start">
      <input
        ref={enteredNameRef}
        type="text"
        placeholder="user name"
        className="input input-bordered w-full max-w-md "
      />
    </div>
    <div className="form-control items-center lg:items-start">
      <input
        ref={enteredEmailRef}
        type="email"
        placeholder="email"
        className="input input-bordered w-full max-w-md "
      />
    </div>
    <div className="form-control items-center lg:items-start mt-6">
      <button type="submit" className="btn btn-sm w-full max-w-md">
        Register
      </button>
    </div>
  </form>
</div>
  • Console.log the reference values inside the function,
//   form handling function
const handleFormSubmission = (e) => {
  e.preventDefault();
  console.log({
    name: enteredName,
    email: enteredEmail,
  });
};
import React, { useRef } from "react";

const SimpleInputForm = () => {
  // reference variable for name
  const enteredNameRef = useRef();
  // reference variable for email
  const enteredEmailRef = useRef();

  //   getting values for name and email from the reference
  const enteredName = enteredNameRef.current.value;
  const enteredEmail = enteredEmailRef.current.value;

  //   form handling function
  const handleFormSubmission = (e) => {
    e.preventDefault();
    console.log({
      name: enteredName,
      email: enteredEmail,
    });
  };

  return (
    <div className="w-2/3 mx-auto">
      <form onSubmit={handleFormSubmission} class="card-body my-20 p-0">
        <div className="form-control items-center lg:items-start">
          <input
            ref={enteredNameRef}
            type="text"
            placeholder="user name"
            className="input input-bordered w-full max-w-md "
          />
        </div>
        <div className="form-control items-center lg:items-start">
          <input
            ref={enteredEmailRef}
            type="email"
            placeholder="email"
            className="input input-bordered w-full max-w-md "
          />
        </div>
        <div className="form-control items-center lg:items-start mt-6">
          <button type="submit" className="btn btn-sm w-full max-w-md">
            Register
          </button>
        </div>
      </form>
    </div>
  );
};

export default SimpleInputForm;
  • Write something on the input fields and submit. Then check the browser dev tool to see the output.

Controlled and Uncontrolled input

It’s basically a primary concept that tells if an element’s control is on react’s hand or not. If setting and working with the state of an HTML element is up to react, can be a controlled input. And else, it’s an uncontrolled input.

If we use reference (useRef()) of an input field, can be an uncontrolled input that we have shown above. And a controlled input example can be shown below,

import { useState } from 'react';
  
function App() {
  const [name, setName] = useState('');
  
  function handleSubmit() {
    alert(`Name: ${name}`);
  }
    
  return (
    <div className="App">
      <h3>Controlled Component</h3>
      <form onSubmit={handleSubmit}>
        <label>Name:</label>
        <input name="name" value={name} onChange={(e) => setName(e.target.value)} />
        <button type="submit">Submit</button>
      </form>
    </div>
  );
}
  
export default App;

Why is this a controlled input?…well, react has control over the input value of the input fields here with state hook. This is why it is a controlled input.