JavaScript

useRef vs. useState: A Quick Guide

React Hooks introduced a powerful way to manage state and side effects within functional components. Two fundamental hooks, useState and useRef, are often used in conjunction to achieve different functionalities. Understanding when to use each hook is crucial for writing efficient and maintainable React components.

In this article, we’ll delve into the differences between useRef and useState, exploring their purposes, use cases, and best practices. By the end, you’ll have a clear understanding of when to reach for useRef and when to use useState.

1. Understanding useRef

Explanation of useRef and its purpose

useRef is a React Hook that creates a mutable reference to a value. Unlike useState, which is used to manage state that triggers re-renders, useRef is primarily used for accessing DOM elements or storing persistent values that don’t require re-renders.

How useRef creates a mutable reference

When you call useRef with an initial value, it creates a reference object. This reference object has a .current property that can be modified directly. Unlike state managed by useState, changes to the .current property do not trigger a re-render of the component.

Use Cases for useRef

Accessing DOM Elements

One common use case for useRef is to access DOM elements directly. By creating a reference to an element using useRef, you can manipulate its properties or trigger events.

import React, { useRef } from 'react';

function MyComponent() {
  const inputRef = useRef(null);

  const handleClick = () => {
    inputRef.current.focus();
  };

  return (
    <div>
      <input   
 type="text" ref={inputRef} />
      <button onClick={handleClick}>Focus Input</button>
    </div>
  );
}

In this example, useRef is used to create a reference to the input element. The handleClick function can then use the reference to focus the input.  

Storing Persistent Values

useRef can also be used to store persistent values that don’t need to trigger re-renders. This is useful for cases where you want to retain a value across component mounts and unmounts.

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

function MyComponent() {
  const countRef = useRef(0);

  useEffect(() => {
    countRef.current++;
  }, []);

  return (
    <div>
      Count: {countRef.current}
    </div>
  );
}

In this example, useRef is used to store a persistent count value. The useEffect hook is used to increment the count on each render, but the component itself doesn’t re-render because the count is stored in the reference.

Creating Custom Hooks

useRef can be used to create custom hooks that need to store persistent values or access DOM elements. For example, you could create a custom hook to manage a timer or track scroll position.

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

function useInterval(callback, delay) {
  const savedCallback = useRef();

  useEffect(() => {
    savedCallback.current = callback;   

  }, [callback]);

  useEffect(() => {
    const id = setInterval(() => {
      savedCallback.current();
    }, delay);
    return   
 () => clearInterval(id);
  }, [delay]);
}

This custom hook uses useRef to store the callback function and useEffect to manage the interval. The savedCallback reference ensures that the correct callback is executed even if the component re-renders.

2. Understanding useState

Explanation of useState and its purpose

useState is a React Hook that allows you to manage state within functional components. It provides a way to declare and update state variables directly within your components. Unlike class components, where state is managed in a separate state object, useState makes it easier to manage state in functional components.

How useState manages state within a component

When you call useState with an initial value, it returns an array with two elements:

  1. The current state value: This is the value that you can use in your component.
  2. A function to update the state: This function takes a new value as an argument and updates the state, triggering a re-render of the component.

Here’s a basic example:

import React, { useState } from 'react';

function MyComponent() {
  const [count, setCount] = useState(0);

  return (
    <div>
      Count: {count}
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

In this example, useState is used to create a state variable count with an initial value of 0. The setCount function is used to update the count when the button is clicked, triggering a re-render of the component.  

Use Cases for useState

Managing component state

useState is primarily used to manage state within a component. This includes things like user input, data fetched from APIs, or any other values that need to be tracked and updated within the component.

Triggering re-renders

When you call the update function returned by useState, it triggers a re-render of the component. This allows you to update the UI based on changes in state.

Creating custom hooks

You can use useState to create custom hooks that manage state. This is a common pattern for encapsulating reusable state management logic within a hook. Sources and related content

3. Key Differences Between useRef and useState

FeatureuseRefuseState
PurposeCreating mutable referencesManaging state
How it worksCreates a reference object with a .current propertyReturns a state value and an update function
Re-rendersDoes not trigger re-rendersTriggers re-renders when the state is updated
Use casesAccessing DOM elements, storing persistent values, creating custom hooksManaging component state, triggering re-renders, creating custom hooks

Key Differences

  • Purpose: useRef is primarily used for creating mutable references, while useState is used for managing state.
  • Re-renders: Changes to the .current property of a useRef object do not trigger re-renders, while changes to the state managed by useState do trigger re-renders.
  • Use cases: useRef is often used for accessing DOM elements, storing persistent values, or creating custom hooks. useState is used for managing component state, triggering re-renders, and creating custom hooks.

When to Use Which

  • Use useRef when:
    • You need to access DOM elements directly.
    • You want to store persistent values that don’t need to trigger re-renders.
    • You’re creating custom hooks that require mutable references.
  • Use useState when:
    • You need to manage state within a component.
    • You want to trigger re-renders based on state changes.
    • You’re creating custom hooks that require state management.

4. Best Practices

In React, both useRef and useState are hooks that serve important roles in managing component behavior, but they have distinct purposes. Understanding when and how to use each effectively can significantly enhance your application’s performance and readability. Below, we present best practices and guidelines for using useRef and useState, helping you choose the right hook for your needs while avoiding common pitfalls and misconceptions.

AspectuseRefuseState
PurposeTo create mutable object references that persist for the full lifetime of the component.To declare state variables that cause a re-render of the component when updated.
Re-rendersDoes not trigger a re-render when the value changes.Triggers a re-render when the state is updated.
Common Use CasesAccessing DOM elements, storing mutable values that do not require rendering (e.g., timers).Managing UI state, form inputs, toggles, counters, and other reactive data.
InitializationCan be initialized with any value, but it’s generally used for mutable values.Initializes state to a value that can change over time and should reflect in the UI.
Updating ValuesUse .current to update the value, e.g., myRef.current = newValue;.Use the state setter function, e.g., setState(newValue);.
Avoiding Common PitfallsDon’t use useRef for state that should trigger re-renders or for persisting values between renders.Avoid using useState for values that don’t need to trigger re-renders; consider useRef instead.
MisconceptionsMany believe useRef can replace useState, but it should only be used for non-reactive values.Some think useState is the only way to manage state, overlooking scenarios where useRef may be more appropriate.

4. Conclusion

In this article, we’ve explored the differences between useRef and useState in React. Understanding when to use each hook is essential for writing efficient and maintainable components.

Key Points:

  • Choose useState for state that needs to trigger re-renders and for complex state management.
  • useRef is primarily used for creating mutable references and accessing DOM elements.
  • useState is used for managing state within components and triggering re-renders.
  • Choose useRef for persistent values that don’t need re-renders and for accessing DOM elements.

Eleftheria Drosopoulou

Eleftheria is an Experienced Business Analyst with a robust background in the computer software industry. Proficient in Computer Software Training, Digital Marketing, HTML Scripting, and Microsoft Office, they bring a wealth of technical skills to the table. Additionally, she has a love for writing articles on various tech subjects, showcasing a talent for translating complex concepts into accessible content.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button