React "useState" Hook: A Comprehensive Guide for Beginners

AsawerAsawer
5 min read

What is useState?

useState is a React hook that allows you to add state to a functional component. Before hooks were introduced in React, you could only manage state using class components. But with hooks, you can now manage state directly in functional components.

Basic Syntax of useState:

const [stateVariable, setStateVariable] = useState(initialValue);
  • stateVariable: This is the state you want to track or manage.

  • setStateVariable: This is the function used to update the state.

  • useState(initialValue): The hook itself, which takes an initial value and returns a pair:

    1. The current state (in this case, stateVariable).

    2. A function to update the state (in this case, setStateVariable).


Example: Shopping List

Let’s learn react & useState using example:

import { useState } from "react";

const ShoppingList = () => {
  const [items, setItems] = useState([]);
  const [name, setName] = useState("");
  const [quantity, setQuantity] = useState("");

  const handleSubmit = (e) => {
    e.preventDefault();

    if (!name || !quantity) return;

    const newItem = {
      name,
      quantity: parseInt(quantity),
    };

    setItems((prevItems) => [...prevItems, newItem]);

    setName("");
    setQuantity("");
  };

  return (
    <div>
      <h1>Shopping Items</h1>
      <form onSubmit={handleSubmit}>
        <div>
          <label>
            Name:
            <input
              type="text"
              onChange={(e) => setName(e.target.value)}
              value={name}
              placeholder="John"
            />
          </label>
        </div>

        <div>
          <label>
            Quantity:
            <input
              type="text"
              onChange={(e) => setQuantity(e.target.value)}
              value={quantity}
            />
          </label>
        </div>

        <button type="submit">Add Item</button>
      </form>

      <div>
        {items.map((item, index) => (
          <li key={index}>
            {item.name} - Quantity: {item.quantity}
          </li>
        ))}
      </div>
    </div>
  );
};

export default ShoppingList;

Now let’s break down how useState works in this example.


1. Managing an Array of Items (items)

const [items, setItems] = useState([]);
  • items: This is the state variable that holds the current list of shopping items. Initially, it’s set to an empty array ([]) because there are no items when the component first renders.

  • setItems: This is the state updater function. It is used to update the items array whenever a new item is added to the list.

Here’s how it works in context:

setItems((prevItems) => [...prevItems, newItem]);
  • When a new item is submitted via the form, setItems is called to update the items array.

  • The spread operator (...prevItems) takes all the items that were already in the array (the previous state) and creates a new array with those previous items, plus the new one (newItem).

  • This ensures that we’re not mutating the existing array directly but rather creating a new version of it. React then re-renders the component to reflect this updated state.


2. Managing Form Inputs (name and quantity)

Name State:

const [name, setName] = useState("");
  • name: This state variable holds the name of the item being typed into the input field.

  • Initial Value: The initial value is an empty string "" because the form input is empty at first.

  • setName: This is the state updater function. It updates the name state whenever the user types something into the input field.

The update happens here:

onChange={(e) => setName(e.target.value)}
  • The onChange event fires every time the input’s value changes. The setName function is called with e.target.value (the current value of the input field) to update the name state.

Quantity State:

const [quantity, setQuantity] = useState("");
  • Similar to name, quantity manages the number of items for the input.

  • Initial Value: It’s also an empty string "" at first.

  • State Updater (setQuantity):

onChange={(e) => setQuantity(e.target.value)}
  • Like with name, the onChange event updates the quantity state with the current value of the input field.

3. Submitting the Form and Updating the State

The form submission logic is handled inside the handleSubmit function:

const handleSubmit = (e) => {
  e.preventDefault();

  if (!name || !quantity) return;

  const newItem = {
    name,
    quantity: parseInt(quantity), // Parse quantity as a number
  };

  setItems((prevItems) => [...prevItems, newItem]); // Add the new item to the list

  setName(""); // Reset the name input field
  setQuantity(""); // Reset the quantity input field
};
  • e.preventDefault(): This prevents the default form submission behavior (which would cause a page reload).

  • Form Validation: Before adding an item, the code checks if both name and quantity fields are filled in (if (!name || !quantity) return;). If either is empty, the function returns early and does not add the item.

  • Creating a New Item Object:

      const newItem = {
        name,
        quantity: parseInt(quantity),
      };
    

    A new object is created with the current name and quantity from the form inputs.

  • Updating the items Array:

      setItems((prevItems) => [...prevItems, newItem]);
    

    This line updates the items array by appending the new item to the existing list, as explained earlier. The state is updated with a new array containing both the previous items and the new one.

  • Resetting the Input Fields:

      setName(""); // Clears the name input field
      setQuantity(""); // Clears the quantity input field
    

    After adding the item, the input fields are reset to empty strings so that the user can start fresh for the next item.


State Lifecycle and Re-renders

Every time you update the state using setItems, setName, or setQuantity, React re-renders the component:

  • When setItems is called, React re-renders the component to update the list of items in the <ul>.

  • When setName or setQuantity is called, React re-renders to update the input fields.

React is declarative, meaning whenever the state changes, React takes care of updating the DOM in the most efficient way. In this example:

  • When a new item is added, the list (<ul>) gets re-rendered with the updated state.

  • When typing into the input fields, React updates the input fields and keeps track of their state values.


Summary of useState in above Example:

  1. useState for multiple states:

    • You have multiple state variables (items, name, and quantity), each tracking a different part of the component (the shopping list and form inputs).
  2. Controlled inputs:

    • name and quantity are controlled inputs. Their values are controlled by React via the useState hook, which ensures that the input field values are always in sync with the component's state.
  3. State updates trigger re-renders:

    • Every time you update the state (e.g., when an item is added to items, or when name and quantity change), React re-renders the component to reflect those changes in the UI
10
Subscribe to my newsletter

Read articles from Asawer directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Asawer
Asawer