React "useState" Hook: A Comprehensive Guide for Beginners
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:
The current state (in this case,
stateVariable
).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 theitems
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 theitems
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 thename
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. ThesetName
function is called withe.target
.value
(the current value of the input field) to update thename
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
, theonChange
event updates thequantity
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
andquantity
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
andquantity
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
orsetQuantity
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:
useState
for multiple states:- You have multiple state variables (
items
,name
, andquantity
), each tracking a different part of the component (the shopping list and form inputs).
- You have multiple state variables (
Controlled inputs:
name
andquantity
are controlled inputs. Their values are controlled by React via theuseState
hook, which ensures that the input field values are always in sync with the component's state.
State updates trigger re-renders:
- Every time you update the state (e.g., when an item is added to
items
, or whenname
andquantity
change), React re-renders the component to reflect those changes in the UI
- Every time you update the state (e.g., when an item is added to
Subscribe to my newsletter
Read articles from Asawer directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by