DEV Community

Digvijay Bhakuni
Digvijay Bhakuni

Posted on

🧠 Understanding State Management in Web Applications

From Cookies to Redux — A Complete Beginner’s Guide


🌍 Introduction

When you open your favorite website, add items to a shopping cart, or log into an app — have you ever wondered how the website “remembers” you even when you refresh or come back later?

This “memory” is made possible by something called State Management.

In this post, we’ll break down what state means, why it’s hard to manage on the web, and explore all the ways developers handle it — from simple cookies to advanced frontend libraries like Redux and Context API.


🔄 What Is “State”?

In simple terms, state means the current data or situation of your app at a given moment.

For example:

  • In a shopping app: items in your cart
  • In a login system: which user is logged in
  • In a to-do app: list of your tasks
  • In a music app: which song is playing and at what time

Whenever something changes (you add a new task, change a setting, or log out), the state of your app changes too.


⚠️ Why State Management Is Needed

The web runs on HTTP, which is a stateless protocol — meaning:

Each request is independent, and the server doesn’t automatically remember what happened before.

If you log into a website, and then open another page, the server doesn’t know it’s still you — unless it’s managing your state somehow.

That’s why web developers use state management techniques: to keep track of users, data, and app behavior across multiple requests, pages, and sessions.


🧩 Types of State in Web Apps

There are generally two main categories of state:

Type Description Example
Client-side State Data stored and managed in the browser UI theme (dark/light), cart items, input fields
Server-side State Data stored and managed on the server Logged-in user info, database records, session data

Let’s go through all the common techniques used for both.


🧠 Part 1: Client-Side State Management

Client-side state is all about what happens in the browser.
It’s fast, doesn’t require a network call, and is great for UI-related information.

1️⃣ JavaScript Variables / In-Memory State

Simplest form — you store values in variables or React state hooks.

let count = 0;
function increase() {
  count++;
  console.log(count);
}
Enter fullscreen mode Exit fullscreen mode

✅ Pros:

  • Fast and easy
  • Great for temporary UI interactions

❌ Cons:

  • Lost on refresh or page reload

Used In: React, Vue, Angular component states.


2️⃣ Browser Storage

a) Local Storage

Stores data permanently in the browser, until manually deleted.

localStorage.setItem("theme", "dark");
let theme = localStorage.getItem("theme");
Enter fullscreen mode Exit fullscreen mode

✅ Persists even after closing the tab or browser
❌ Accessible only by frontend JavaScript (no security layer)

Good for: saving themes, preferences, small data.


b) Session Storage

Similar to local storage, but cleared when the tab closes.

sessionStorage.setItem("cart", JSON.stringify(items));
Enter fullscreen mode Exit fullscreen mode

✅ Isolated to one tab/session
❌ Disappears after closing the tab

Good for: temporary data like in-progress forms or checkout steps.


c) Cookies

Small pieces of data stored in the browser, sent automatically with every HTTP request.

document.cookie = "username=John; expires=Fri, 31 Dec 2025 23:59:59 GMT";
Enter fullscreen mode Exit fullscreen mode

✅ Server can read cookies automatically
✅ Can persist across sessions
❌ Limited storage (~4KB), and needs security precautions

Good for: sessions, authentication tokens, small preferences.


3️⃣ Frontend State Libraries

Modern web apps are interactive and complex.
That’s why frameworks like React, Vue, and Angular introduced state management libraries to handle component-level and app-wide state efficiently.

🌀 React Context API

Used to share state across multiple components without passing props down manually.

const ThemeContext = React.createContext("light");
Enter fullscreen mode Exit fullscreen mode

✅ Easy for small–medium apps
❌ Can become messy for very large applications


⚙️ Redux

A centralized store that holds the entire app state in one place.

store.dispatch({ type: "ADD_TODO", payload: "Buy milk" });
Enter fullscreen mode Exit fullscreen mode

✅ Predictable and debuggable
✅ Works well in large apps
❌ Slightly complex setup

Used In: React, Angular, and even Flutter (through Redux-like libraries).


📦 Zustand, MobX, Pinia (Vue), NgRx (Angular)

Modern alternatives for simpler or more reactive state management.

✅ Less boilerplate
✅ Easier learning curve
❌ Often limited to the ecosystem they’re built for


🖥️ Part 2: Server-Side State Management

Server-side state keeps track of who you are and what you’re doing on the server — essential for authentication, user sessions, and data persistence.


1️⃣ Sessions

When you log in:

  1. Server creates a session object and stores it in memory or a database.
  2. Server gives the browser a Session ID (usually in a cookie).
  3. Each time the browser makes a request, it sends the session ID back.
  4. Server checks the session ID and retrieves your user data.

Example:

Set-Cookie: sessionId=abc123; HttpOnly
Enter fullscreen mode Exit fullscreen mode

✅ Secure (data is stored server-side)
❌ Can consume memory if many users are online

Used In: Express.js, Django, Spring Boot (via session management).


2️⃣ JWT (JSON Web Tokens)

JWTs are stateless tokens that carry user information securely between client and server.

When you log in:

  1. Server creates a token:
   { "user": "john", "role": "admin" }
Enter fullscreen mode Exit fullscreen mode
  1. Server signs it with a secret key and sends it to the client.
  2. Client stores it (in cookies or localStorage).
  3. Each request includes the token in headers:
   Authorization: Bearer <token>
Enter fullscreen mode Exit fullscreen mode
  1. Server verifies the token — no session storage needed.

✅ Fast and scalable
✅ Works well for APIs and mobile apps
❌ Must handle token expiry and security carefully


3️⃣ Database State

All permanent data — user info, settings, orders — lives in a database.
State changes here are the most persistent form (they survive any restart or reload).


🧭 Putting It All Together

Most real-world apps use a mix of all these techniques.

For example:

  • Frontend: React manages UI state, Context stores theme mode.
  • Browser: JWT stored in localStorage.
  • Server: Uses JWT verification + database state for user data.

Flow Example:

Login → Server creates JWT → Browser stores JWT
→ Every API request includes JWT → Server verifies → Returns data
→ React updates UI state → Local storage remembers preferences
Enter fullscreen mode Exit fullscreen mode

🚀 Best Practices

✅ Use HTTP-only cookies for storing tokens securely.
✅ Don’t overuse global state — local state is simpler and faster.
✅ Keep sensitive data on the server, not in browser storage.
✅ Use Redux or Context API only when multiple components need the same data.
✅ Clear session or localStorage on logout.


🧠 Summary Table

Type Where Stored Lifespan Use Case
In-memory variables Browser RAM Until refresh Temporary UI logic
Local Storage Browser Persistent Preferences, tokens
Session Storage Browser Until tab close Temporary data
Cookies Browser/Server Configurable Auth sessions
Sessions Server Until logout Login systems
JWT Client & Server Token expiry Stateless auth
Redux / Context / MobX Browser memory Until refresh UI + app-wide state

🧩 Conclusion

State management is what makes your web app feel alive.
It keeps your experience smooth and personal — even across reloads, tabs, and devices.

  • Frontend handles UI state (React, Redux, etc.).
  • Backend ensures security and persistence (Sessions, JWT, Databases).
  • Together, they create a seamless, stateful web experience on top of the stateless web.

“Without state management, every page refresh would be like meeting your app for the first time.”

Top comments (0)