Understanding React State, Hooks, useState, and Suspense — Visakh Vijayan
← React.js Understanding React State, Hooks, useState, and Suspense June 3, 2026
Understanding React State, Hooks, and Suspense
Introduction
In the previous articles, we learned why React exists, how JSX works, and how React renders user interfaces. The next step is understanding how React components become dynamic.
A static component always renders the same output. Real applications, however, need to respond to user interactions, API responses, and changing data.
This is where hooks and state come into the picture.
In this article, we'll explore React Hooks, component state, the useState hook, and how modern React uses Suspense and use() to handle asynchronous data.
What Are Hooks?
Hooks are functions that add special functionality to React components.
By convention, all hooks start with the word use.
Some common examples include:
useState()
useEffect()
useContext()
useMemo()
use()
Hooks allow React components to:
Store state
Perform side effects
Access context
Optimize performance
Work with asynchronous data
Without hooks, React function components would simply be functions that return JSX.
Hooks give components additional capabilities while keeping them as functions.
What is State?
State is the data a component owns at any given moment.
Consider a counter component.
The count value changes over time.
This changing data is called state.
A useful way to think about state is:
State represents the current memory of a component.
Whenever state changes, React updates the user interface to match the new state.
Adding State with useState The simplest way to add state to a component is through the useState hook.
import { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<button
onClick={() => setCount(count + 1)}
>
Count: {count}
</button>
);
}
Whenever setCount is called, React updates the state and schedules a re-render.
State Updates Demonstrate Declarative Programming State updates are one of the best examples of React's declarative model.
In traditional JavaScript, we might manually update the DOM:
document.getElementById("counter")
.textContent = count + 1;
In React, we update state instead:
We simply describe the new state.
React determines what changed and updates the DOM for us.
What Happens When State Changes? When a state update occurs:
React performs the following steps:
State changes.
The component renders again.
React creates a new Virtual DOM.
React compares the old and new Virtual DOM trees.
The browser receives only the necessary updates.
The Traditional Way of Fetching Data For many years, React applications fetched data using useEffect.
function Users() {
const [users, setUsers] = useState([]);
useEffect(() => {
fetch("/api/users")
.then(res => res.json())
.then(setUsers);
}, []);
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
The component renders before the data is available and renders again once the data arrives.
Enter Suspense Suspense allows React to display fallback content while a component is waiting for something.
<Suspense fallback={<p>Loading...</p>}>
<Users />
</Suspense>
If the wrapped component is not ready, React displays the fallback UI until rendering can continue.
The use Hook Modern React introduces the use() hook for reading asynchronous values.
const users = use(usersPromise);
If the promise has not completed, React pauses rendering and lets Suspense display a fallback.
When the promise resolves, React retries rendering and provides the data.
useEffect vs use + Suspense
useEffect Render Component
↓
Fetch Data
↓
Update State
↓
Render Again
The component renders before data is available.
use + Suspense Attempt Render
↓
Data Not Ready
↓
Show Suspense Fallback
↓
Data Ready
↓
Render Component
The component only renders when the required data exists.
Summary
Hooks add special functionality to components.
Hooks always begin with use.
State represents a component's data at a particular moment.
useState is the simplest way to add state.
Updating state is a great example of declarative programming.
Suspense provides loading fallbacks for asynchronous rendering.
use() and Suspense allow components to wait for data before rendering.
Unlike useEffect, modern React can delay rendering until the required data is available.