Table of contents
Text Link
Text Link

Mastering the useState Hook in React

Before we learn about the useState hook, let’s see what state is and what role it plays in working with React hooks.

State

Our application always contains data that we display on the web page. This data can be changed, updated, or deleted. To store this data and ensure it is displayed in its most current form, we use state. You might wonder why not simply use variables? The issue with using plain variables is that, even though we can update them, these changes will not be reflected on our application's page.

In this video, we observe that updating the variable does not result in a visible change, even though the variable itself is updated.

Here is a video demonstrating the concept of state.

If we store our data in the state and modify it, we will see the changes immediately. This is because the state stores our data and triggers a re-render of the page upon any data updates.

React state can store any type of data (e.g. string, object, boolean, array of values, function, etc.)

React has taken care of developers by creating a hook that helps us to work with the state.

useState Hook. Basics

To start working with the useState hook, you should first import it.

import { useState } from "react";

To begin using the useState hook, you must initialize it within your functional component.

const [value, setValue] = useState(0);

Where:

value is the variable that stores the current state value we wish to track,

setValue is a function that updates this value and triggers a re-render of the function component.

In your React component, you can use as many state variables as you wish. The number depends on the complexity of your component and the nature of the data it manages.

 

Below, you'll find an example of a React component named SquareComponent. This component demonstrates the use of three distinct state variables to control various aspects of a square's appearance. The state variables include:

 

color: Manages the background color of the square.

borderRadius: Controls the border radius of the square.

size: Determines the size of the square in pixels.

 

The component showcases how state in React can be used to dynamically modify the style properties of an HTML element. The changes in the state are reflected immediately in the square's appearance, providing an interactive and visual representation of state management in React.

Share this article
Get more articles
like this
Thank you! Your submission has been received!
Oops! Something went wrong.

Level up Frontend skills and advance your career

• Wide range of learning tracks for beginners and experienced developers

• Study at your own pace with your personal study plan

• Focus on practice and real-world experience

Lear Frontend Free
No creadit card required

useState Hooks in React and Asynchronicity

One of the key aspects to understand when working with the useState hook in React is its asynchronous nature. When we call the state update function provided by useState, such as setValue, React schedules the state update but does not execute it immediately. This means that if we try to access the state immediately after its update, we are likely to encounter the previous, unchanged value. Therefore, using this hook does not guarantee that the value will be updated instantly after the state change.

What should we do in this case?

React itself recommends using an updater function:

setCount(count => count + 1)

In this example, count => count + 1 is the updater function. It takes the current state value (count) and calculates the next state based on it.

useState Hook. Updating Objects and Arrays

When updating objects and array elements in the state, it is necessary to be careful. The issue is that with incorrect updating, you may lose all the data.

const [profile, setProfile] = useState({
  name: 'John Doe',
  age: 30,
});

If we try to update only one field, for example, the age, we will lose the rest of the data (in our case the name).

const updateProfile = () => {
  setProfile({age: 31});
}

The solution -- use the spread operator or other methods to update objects to preserve the other fields.

const updateProfile = () => {
  setProfile({...profile, age: 31});
}

// The same rules for arrays:
const [array, setArray] = useState([1, 2, 3]);

const updateArray = () => {
  setArray([...array, 4]);
}

When to use useState Hook

At first glance, it might seem that useState should be used whenever we change any variable. But this is not the case! To understand whether we need to use useState or not, we need to ask ourselves the following questions:

  • Do we have to preserve state between renders? If your component has to retain data or state between renders (for example, the value of a counter), then useState is ideal for this.
  • Does the state change in response to user actions? If the state changes as a result of user interactions, such as entering text, selecting options, or pressing buttons, then this is a clear indication for using useState.
  • Do data changes lead to changes in the component's interface? If you want changes in data to be immediately reflected in the user interface, for example, when updating a list or changing the style of an element, then useState is necessary.
  • Is there a local state unrelated to other components? If the state is part of the internal logic of the component and does not require global management or data transfer between components, then useState is suitable for this task.
  • Is there a need for toggling interface elements or managing modal windows? If you are working with elements that need to be shown or hidden (such as pop-ups or dropdown menus), then useState is perfect for managing their visibility.

 

When NOT to Use the useState Hook

  • For constant or immutable Data: If the data does not change during the component's lifecycle, for example, constants or props that do not require changes, using useState is unnecessary.
  • Complex or global state: For managing complex or global state that needs to be accessible in many components, it's better to use the Context API or specialized state management libraries like Redux or MobX.
  • Computed data: For data that can be calculated directly from other states or props, use useMemo() or compute them directly in the rendering method to avoid unnecessary use of state.
  • State that does not affect rendering: If changing the state does not lead to re-rendering or does not affect the component's output, probably, the state is not needed. In such cases, you can use useRef or regular variables.

Final Thoughts

Mastering the React useState hook is the key to creating responsive and interactive React applications. It is a tool that elegantly handles state changes, ensuring that components remain dynamic and user-friendly. As you dive deeper into React code, remember that useState functions is more than just state management; it's about unlocking the full potential of your app's interactivity.

Related Hyperskill topics

Get more articles like this
Thank you! Your submission has been received!
Oops! Something went wrong.

More on this