0
0
ReactComparisonBeginner · 4 min read

UseRef vs useState in React: Key Differences and When to Use Each

useState is for managing state that triggers UI updates when changed, while useRef holds mutable values that persist across renders without causing re-renders.
⚖️

Quick Comparison

Here is a quick side-by-side comparison of useRef and useState in React.

FactoruseStateuseRef
PurposeStores state that triggers UI updatesStores mutable values without triggering UI updates
Triggers re-render?Yes, on state changeNo, value changes do not cause re-render
Initial valuePassed as argument to useStatePassed as argument to useRef
Common use casesUI state like form inputs, togglesAccessing DOM elements, storing timers or mutable variables
Value persistencePersists across rendersPersists across renders
Setter functionYes, to update stateNo setter, value changed directly on .current
⚖️

Key Differences

useState is designed to hold data that affects what the user sees on the screen. When you update state with useState, React re-renders the component to reflect the new state. This makes it perfect for things like toggling visibility, updating text, or tracking user input.

On the other hand, useRef holds a mutable object with a current property that you can change without causing a re-render. This is useful when you want to keep track of values that don't need to update the UI, such as timers, previous values, or references to DOM elements.

In summary, use useState when changes should update the UI, and use useRef when you want to keep data around without triggering a render.

⚖️

Code Comparison

This example shows how to count button clicks using useState. The count updates on the screen each time the button is clicked.

jsx
import React, { useState } from 'react';

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

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  );
}
Output
You clicked 0 times (updates to 1, 2, 3... as button is clicked)
↔️

useRef Equivalent

This example uses useRef to keep track of clicks without causing the component to re-render. The count updates internally but the UI does not change.

jsx
import React, { useRef } from 'react';

export default function ClickCounterRef() {
  const countRef = useRef(0);

  function handleClick() {
    countRef.current += 1;
    console.log(`Clicked ${countRef.current} times`);
  }

  return (
    <div>
      <p>Click the button and check the console</p>
      <button onClick={handleClick}>Click me</button>
    </div>
  );
}
Output
UI shows static text; console logs: Clicked 1 times, Clicked 2 times, etc. on each click
🎯

When to Use Which

Choose useState when: you want React to update the UI based on changes, such as showing new text, toggling elements, or updating form inputs.

Choose useRef when: you need to keep track of values that do not affect rendering, like timers, previous values, or direct DOM references.

Using the right hook helps keep your app efficient and your code clear.

âś…

Key Takeaways

useState triggers UI updates when its value changes.
useRef holds mutable values without causing re-renders.
Use useState for data that affects what the user sees.
Use useRef for storing values that don’t need to update the UI.
Choosing the right hook improves app performance and clarity.