DEV Community

ABISHEK M
ABISHEK M

Posted on

useState in React

When building interactive web applications with React, we often need to store values that can change over time. For example, a counter value can increase, a user's name can change, or a login status can switch between logged in and logged out. React provides a Hook called useState to handle these changing values.

What is useState?

useState is a React Hook that allows functional components to create and manage state.

State is a value that a component needs to remember between renders. When the state changes, React re-renders the component and updates the user interface.

The basic syntax is:

const [state, setState] = useState(initialValue);
Enter fullscreen mode Exit fullscreen mode

For example:

const [count, setCount] = useState(0);
Enter fullscreen mode Exit fullscreen mode

Here, count is the current state value, setCount is the function used to update the state, and 0 is the initial value.

Importing useState

Before using useState, we need to import it from React:

import { useState } from "react";
Enter fullscreen mode Exit fullscreen mode

We can then use it inside a functional component.

Understanding State and Setter Function

Consider this example:

const [count, setCount] = useState(0);
Enter fullscreen mode Exit fullscreen mode

Initially, the value of count is 0.

If we want to change it to 5, we should use:

setCount(5);
Enter fullscreen mode Exit fullscreen mode

After the state update, React re-renders the component and the new value becomes available.

We should not directly modify the state like this:

count = 5; // ❌
Enter fullscreen mode Exit fullscreen mode

Instead, we should use the setter function:

setCount(5); // ✅
Enter fullscreen mode Exit fullscreen mode

The setter function tells React that the state needs to be updated.

Example: Counter

A simple counter is one of the best ways to understand useState.

import { useState } from "react";

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

  return (
    <>
      <h1>{count}</h1>

      <button onClick={() => setCount(count + 1)}>
        Increase
      </button>
    </>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Initially, the screen displays 0. When the button is clicked, setCount(count + 1) updates the state. React then re-renders the component, and the screen displays the updated value.

The flow is:

User clicks button
        ↓
setCount()
        ↓
State changes
        ↓
React re-renders
        ↓
UI updates
Enter fullscreen mode Exit fullscreen mode

What is Re-rendering?

A re-render means React runs the component again to determine what the updated user interface should look like.

For example, if:

count = 0
Enter fullscreen mode Exit fullscreen mode

and we call:

setCount(1);
Enter fullscreen mode Exit fullscreen mode

React schedules the state update and renders the component again with the updated state.

The browser does not perform a complete page refresh. React updates the necessary part of the UI.

State as a Snapshot

React treats state as a snapshot for each render. This means the value of a state variable belongs to the particular render in which it was read.

For example:

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

  function handleClick() {
    setCount(count + 1);
    console.log(count);
  }

  return <button onClick={handleClick}>{count}</button>;
}
Enter fullscreen mode Exit fullscreen mode

If count is 0 in the current render, calling setCount(1) does not immediately change the count variable inside that same function execution. The current render still sees 0. React processes the update and provides 1 in the next render.

This concept is often described as state being a snapshot.

Functional State Updates

Sometimes the new state depends on the previous state. In such situations, we can use a functional updater:

setCount(prev => prev + 1);
Enter fullscreen mode Exit fullscreen mode

Here, prev represents the state value React provides to the updater function.

For example:

setCount(prev => prev + 1);
setCount(prev => prev + 1);
Enter fullscreen mode Exit fullscreen mode

If the initial value is 0, React processes the updates sequentially:

0 → 1 → 2
Enter fullscreen mode Exit fullscreen mode

Therefore, the final value is 2.

The functional updater is especially useful when multiple updates depend on the previous state.

Array Destructuring in useState

The syntax:

const [count, setCount] = useState(0);
Enter fullscreen mode Exit fullscreen mode

uses JavaScript array destructuring.

The first value represents the current state, while the second value represents the setter function.

For example:

const [name, setName] = useState("");
Enter fullscreen mode Exit fullscreen mode

Here:

  • name → current state value
  • setName → function used to update the state
  • "" → initial state value

The names can be changed depending on what the state represents.

Examples:

const [age, setAge] = useState(21);

const [name, setName] = useState("");

const [isLoggedIn, setIsLoggedIn] = useState(false);
Enter fullscreen mode Exit fullscreen mode

useState with Input Fields

useState is commonly used with form inputs.

For example:

import { useState } from "react";

function App() {
  const [name, setName] = useState("");

  return (
    <>
      <input
        value={name}
        onChange={(event) => setName(event.target.value)}
      />

      <h2>Hello {name}</h2>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

When the user types something into the input, onChange runs.

event.target.value gives the current value of the input.

For example, if the user types:

Abi
Enter fullscreen mode Exit fullscreen mode

then:

event.target.value
Enter fullscreen mode Exit fullscreen mode

contains:

"Abi"
Enter fullscreen mode Exit fullscreen mode

and:

setName(event.target.value);
Enter fullscreen mode Exit fullscreen mode

updates the state.

The flow becomes:

User types
    ↓
onChange
    ↓
event.target.value
    ↓
setName()
    ↓
State changes
    ↓
Re-render
    ↓
UI updates
Enter fullscreen mode Exit fullscreen mode

This pattern is commonly used in login forms, signup forms, search boxes, todo applications, and many other React applications.

Different Types of State

useState can store different types of JavaScript values.

Number

const [count, setCount] = useState(0);
Enter fullscreen mode Exit fullscreen mode

String

const [name, setName] = useState("");
Enter fullscreen mode Exit fullscreen mode

Boolean

const [isLoggedIn, setIsLoggedIn] = useState(false);
Enter fullscreen mode Exit fullscreen mode

Array

const [todos, setTodos] = useState([]);
Enter fullscreen mode Exit fullscreen mode

Object

const [user, setUser] = useState({
  name: "",
  age: 0
});
Enter fullscreen mode Exit fullscreen mode

The type of state depends on what information the component needs to remember.

Why is useState Important?

Without state, creating interactive React applications would be much more difficult. useState allows components to respond to user actions and remember changing information.

For example, state can be used for:

  • Counter applications
  • Login forms
  • Signup forms
  • Todo lists
  • Search boxes
  • Dark mode
  • Dropdown menus
  • Like buttons
  • Shopping carts
  • Form validation

Conclusion

useState is one of the most important concepts for anyone learning React. It allows functional components to store values that can change over time and update the user interface when those values change.

The basic pattern is:

const [value, setValue] = useState(initialValue);
Enter fullscreen mode Exit fullscreen mode

The key ideas to remember are:

useState()
    ↓
Creates state
    ↓
State has a current value
    ↓
Setter function updates the state
    ↓
React re-renders
    ↓
UI displays the updated state
Enter fullscreen mode Exit fullscreen mode

Once you understand useState, concepts such as forms, event handling, conditional rendering, todo applications, and many other React features become much easier to understand.

Top comments (0)