DEV Community

Saleh Mubashar
Saleh Mubashar

Posted on • Updated on

useRef or useState, which is better?

header
Hi guys!
In this post we will be learning what the useRef and useState hooks are, their differences and when to use which.
The code examples in this post will involve only functional components, however most of the differences and uses cover both class and functional components

Check out my blog too!


The useState hook

useState is a built in react hook that allows you to store information as states in a variable. It lets you add React states to functional components.
In the example below, useState() declares the state variable while the the value is stored in the count variable. setCount is the function used to update this value.

//import useState from react
import React, { useState } from 'react';
function Count() {
  // Declare a new state variable called count
  const [count, setCount] = useState(0);
Enter fullscreen mode Exit fullscreen mode

The useRef hook

The useRef hook is a built-in React hook that takes one argument or parameter as its initial value and returns a reference or persisted mutable values. This reference, or ref for short, contains the value which can be retrieved using the current property.
We can also store user inputs in refs and display the collected data like this:

//import useRef hook
import React, { useRef } from "react"
export default function App() {
  //create a variable to store the reference 
  const nameRef = useRef();
  function handleSubmit(e) {
    //prevent page from reloading on submit
    e.preventDefault()
    //output the name
    console.log(nameRef.current.value)
  }
  return (
    <div className="container">
      <form onSubmit={handleSubmit}>
        <div className="input_group">
          <label>Name</label>
          <input type="text" ref={nameRef}/>
        </div>
        <input type="submit"/>
      </form>
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

useRef vs useState

  1. Data or values stored in a reference or ref remains the same, even after component re-rendering, unlike states. So, References do not affect component rendering but states do.

  2. useState returns 2 properties or an array. One is the value or state and the other is the function to update the state. In contrast, useRef returns only one value which is the actual data stored.

  3. When the reference value is changed, it is updated without the need to refresh or re-render. However in useState, the component must render again to update the state or its value.

When to use Refs and States

Refs are useful when getting user input, DOM element properties and storing constantly updating values.
However if you are storing component related info or use methods in components states are the best option.

So in conclusion, both the hooks have their fair bit of pros and cons, and they will be utilised according to the situation and use.


Thanks for reading!.
Note!: There probably is much more that could have been mentioned here but in short, these were the most important differences.

Complete Tutorial on useRef is uploaded at Hubpages

Check out my blog!

Oldest comments (15)

Collapse
 
lexlohr profile image
Info Comment hidden by post author - thread only accessible via permalink
Alex Lohr

I'd take useState, because I'd get useRef for free by writing:

const useRef = (initial) => useState({ current: initial })[0];
Enter fullscreen mode Exit fullscreen mode

This way, I can still decide if I want state changes to trigger reconciliation or not.

Collapse
 
joaolss profile image
João Lucas Silva

Not a very good idea, useState has much more logic behind it bc the component is aware of it. Also you can create internal problems during reconciliation phase if you change state outside updater function, so if you want mutable variables without triggering rerender you should use useRef, in any case, stick with react documentation instead of accidentally creating anti-patterns

Collapse
 
lexlohr profile image
Alex Lohr

Actually, both useRef and useState internally represent memoized values, i.e. values returned by a function that keeps the reference. The only difference is that for useState, you also get a setter that reactively changes the reference in the memo. If you don't change the reference, the reconciler never notices the change, which is exactly what useRef does: provide a memo with a reference to a value without a setter to ever create a new reference in the memo.

Even Dan Abramov himself commented as such on Twitter. In any case, the original question was "which is better" and the answer is: useState provides both functionalities if need be.

Obviously, you should always use the right tool for the job, but don't go around accusing someone of creating problems or anti-patterns unless you are really sure of your case.

Thread Thread
 
salehmubashar profile image
Saleh Mubashar

you are right.
I did cover most of the differences in my post, but then again I am still learning despite a decent amount of experience in React.
In the end, 'which is better' was never addressed and I wrote in the conclusion always use the right tool for the job, as you stated as well
Cheers :)

Thread Thread
 
joaolss profile image
João Lucas Silva

Yeah, in the context of keeping a reference those are obviously the same, but still holds that you’re carring unnecessary logic with useState call, despite trashing the updater, it is still been created, and yes, i give you that if you never use the updater probably you will not have problems mutating the state, but that’s risky since mutating state both ways will surely bring problems and i have seen this a lot, so this is still a anti-pattern since 1.it’s against React’s documentation, 2. Create unecessary logic and 3. Can quickly lead to problems if you are not carefull, so this is the wrong comment to do in a beginner’s guid post

Thread Thread
 
salehmubashar profile image
Saleh Mubashar

guys relax !
I just wrote a simple beginner friendly tutorial so obviously i will not be going into that much depth. Both of you are right in your own ways but this argument will lead to nowhere.
Besides I am no React genius, so I am still learning too
Thanks :)

Thread Thread
 
joaolss profile image
João Lucas Silva

I agree with you, I just think that empathy is also remembering that not everyone has the same knowledge as you, and im all ok with people posting quirks about languages and frameworks, but we should always bring attetion to pitfalls and drawbacks whenever possible, someone that is starting on React might see such a comment and when replicating it, having much more headache than otherwise. Sorry for been agressive, just be kind to other and explain the drawbacks when possible

Thread Thread
 
salehmubashar profile image
Saleh Mubashar • Edited

agreed.
Thanks for your inputs and advices, I learnt a few new things too!
However, I think there are no major mistakes on my post right?
I mean in general the differences I mentioned are true and I also researched a few other React articles and the official documentation as well.
Lastly can i delete this thread, because imagine if a newcomer or beginner (my target audience) reads this and gets confused. (Btw I agree with what you said to the person who started the thread, he should not have commented something advanced on a beginner level tutorial)
thanks

 
lexlohr profile image
Alex Lohr

Yes, mutating state both ways is risky, but since I throw away the updater in my example, that risk is exactly 0.0000.

Also, just because it's not documented, it is not necessarily an anti-pattern. There are a lot of nice patterns nowhere to be found in the react documentation. Yes, creating an unneeded function that will be immediately eaten by the garbage collector may not be the best idea, but the point of the example was to show the relation between both hooks in terms even a beginner should be able to understand and not to show a best practice and 3. No again; if you want to warn about problems, show the code that causes the problem inside the given scope. Don't blame me for bad code you've seen elsewhere.

Thread Thread
 
lexlohr profile image
Alex Lohr

You have still failed to show why they would have a headache. Also, I would trust even beginners to be able to see that a useRef method is already available, so they wouldn't have to create their own and therefore recognize that this example was meant to illustrate the difference between useState and useRef and not more.

Thread Thread
 
salehmubashar profile image
Saleh Mubashar

by headache i meant 1) it may be overwhelming to new learners. 2) I am sure I conveyed my point in the post while trying to stay as simple as possible and lastly neither is better, its just about usage

Collapse
 
gyandeeps profile image
Gyandeep Singh • Edited

Mostly I use the rule, if state shows up on the UI than useState else useRef. That way you save up on unnecessary renders. Obviously there might be exceptions such as to if you want to trigger other hooks etc

Collapse
 
salehmubashar profile image
Saleh Mubashar

yup that is a very good approach!

Collapse
 
mynepeacepox profile image
Info Comment hidden by post author - thread only accessible via permalink
The_real_pox

Hey, everyone.
I have been trying to upload an image on visual code while coding but it keeps on breaking what am I missing?

Collapse
 
mrdulin profile image
official_dulin

They are totally different things. Can't compare.

Some comments have been hidden by the post's author - find out more