DEV Community 👩‍💻👨‍💻

Cover image for When to use useRef() instead of useState()
Isabelle M.
Isabelle M.

Posted on

When to use useRef() instead of useState()

In React, hooks are a way to use state and other React features without having to generate a class component. One of the most frequently used hook is useState(), however on occasion useRef() might be a better and more efficient way to manage state.
A common use case is handling a form input field when the submit button is clicked. For example, lets look at the following code snippet:

const [email, setEmail] = useState('');
const [password, setPassword] = useState('');

const handleSubmit = (e) => {
  e.preventDefault();
  console.log(email, password);
};

return (
  <form onSubmit={handleSubmit}>
    <input
      type="email"
      value={email}
      onChange={(e) => setEmail(e.target.value)}
    />
    <input
      type="password"
      value={password}
      onChange={(e) => setPassword(e.target.value)}
    />
    <button type="submit">Submit</button>
  </form>
);
Enter fullscreen mode Exit fullscreen mode

In the above example, we have two input fields, one for the email and one for the password. When the submit button is clicked, the values of the two input fields are logged to the console. The useState() hook is used to manage the state of the two input fields. Although, this code does what it's supposed to do, it also causes the component to re-render every time the input fields are changed.

This is due to the usage of the useState() hook, which by definition causes the component to re-render every time the state is changed. This is not a problem in this example, but in a more complex application, this can cause performance issues. To avoid this, we can use the useRef() hook instead of useState().

const email = useRef('');
const password = useRef('');

const handleSubmit = (e) => {
  e.preventDefault();
  console.log(email.current, password.current);
};

return (
  <form onSubmit={handleSubmit}>
    <input
      type="email"
      value={email.current}
      onChange={(e) => (email.current = e.target.value)}
    />
    <input
      type="password"
      value={password.current}
      onChange={(e) => (password.current = e.target.value)}
    />
    <button type="submit">Submit</button>
  </form>
);
Enter fullscreen mode Exit fullscreen mode

When to use useRef() instead of useState()

A rule of thumb is to use useState when you need to re-render the component when the state changes and useRef when you don't need to re-render the component when the state changes.
Here are some examples of when to use useRef instead of useState:

  • When you need to store a value that does not trigger a re-render when it is updated.
  • When you need to store a value that is not used in the render method.
  • When you need to store a value that persists for the lifetime of the component.

Top comments (3)

Collapse
 
dubcee93 profile image
dubcee93

Thanks for the post - I had to learn the difference between these a month or two ago to improve a contribution to an open-source project and was happy to read this quick post as a reminder of it. Have a good day!

Collapse
 
olsard profile image
olsard

Cool, thanks a lot for sharing!

Collapse
 
xoxsimba profile image
nannuflay

thanks

Classic DEV Post:

Understanding git through images