Module 1
Topic 3

Global State

Understanding state that is shared across many parts of your app — the foundation of scalable Flutter applications.

Flutter Docs – State Management Introduction Ephemeral vs App State
What Is Global State?

In contrast to local (ephemeral) state , global state (also called app state ) is data that is shared across many parts of your application. It's the state that multiple widgets need to read, update, or react to.

🌐 Global State Defined

Global state is data that is not contained within a single widget. It is accessible to multiple widgets across the widget tree and typically outlives individual widget instances. It often represents the core data of your application, such as user authentication, preferences, or the contents of a shopping cart.

  • ✓ Used by multiple widgets in different parts of the app
  • ✓ Often persisted across app restarts
  • ✓ Managed with state management solutions (Riverpod, Provider, BLoC, etc.)
Why Global State Matters

As your app grows, you'll encounter scenarios where the same piece of data is needed in multiple places. For example:

  • User authentication status – needed in the login screen, profile page, and navigation drawer.
  • Shopping cart items – accessed in the product list, cart page, and checkout screen.
  • Theme settings – used throughout the app to adjust UI colors and styles.

Without a proper way to share this data, you'd be forced to pass it down the widget tree through constructors — a pattern known as prop drilling .

The Problem of Prop Drilling

Prop drilling is the practice of passing data from a parent widget down to child widgets that don't actually need the data themselves, but need to forward it to a deeper widget that does.

⚠️ The Downsides of Prop Drilling

  • Boilerplate – you have to add parameters to many intermediate widgets.
  • Fragile code – changing the data structure requires updating many files.
  • Hard to maintain – it's unclear which widgets depend on the data.
  • Reduced testability – widgets become tightly coupled to the data flow.

Example of Prop Drilling

This is a simple example; imagine a deep tree with 10 intermediate widgets. It's tedious and error-prone.

Global State Management Solutions

Flutter provides several ways to make data available to many widgets without prop drilling. These solutions generally fall into three categories:

🔗
InheritedWidget
The foundation of the framework — used by Theme, MediaQuery, etc.
📦
Provider
A wrapper around InheritedWidget, simpler to use.
🌊
Riverpod
A provider-like solution with more features and testability.
🎯
BLoC
Business Logic Component — uses streams and events.
GetX
A lightweight solution with state management, routing, and more.
🔄
MobX
Reactive state management based on observables.

In this course, we'll focus on Riverpod because it's modern, robust, and recommended by the Flutter team for new projects. However, understanding the concept of global state is independent of the tool you choose.

Simple Example: Using Provider

To illustrate how global state works, here's a minimal example using the Provider package. This is a simple counter that can be accessed from multiple screens.

✅ How This Works

  • CounterModel holds the global state and notifies listeners when it changes.
  • ChangeNotifierProvider makes the model available to all widgets in its subtree.
  • Provider.of<CounterModel>(context) gets the model and listens for changes.
  • When increment() is called, notifyListeners() triggers a rebuild of any widget that depends on it.
When to Use Global State vs Local State

📦 Local State

  • Data used by a single widget
  • No need to share across screens
  • Temporary and not persisted
  • Managed with setState()

🌐 Global State

  • Data used by multiple widgets
  • Shared across screens
  • Often persisted (e.g., user session)
  • Managed with state management solutions

💡 Rule of Thumb

If two or more widgets need to read or modify the same piece of data, it's likely global state . If the data is only relevant to a single widget, it's local state .

Common Pitfalls
❌ Mistake 1: Overusing global state for everything

Not everything needs to be global. Overusing global state leads to unnecessary rebuilds and makes your app harder to reason about. Keep local state local when possible.

✅ Correct: Use global state only when needed

Start with local state and only promote to global when you find yourself sharing data between widgets.

❌ Mistake 2: Mutating global state directly without notifying

If you're using a model with ChangeNotifier , you must call notifyListeners() after changing the state, or the UI won't update.

✅ Correct: Always notify listeners after state changes

Wrap state mutations in methods that call notifyListeners() to ensure the UI reflects the new state.

❌ Mistake 3: Not disposing state objects

If your global state holds resources like streams or controllers, you must dispose of them properly to prevent memory leaks.

✅ Correct: Dispose of resources

Implement dispose() in your state classes and call it when the widget is removed from the tree.

🎯 Key Takeaway

Global state is shared across many parts of your app and is essential for building scalable applications. Avoid prop drilling by using a state management solution. In this course, we'll use Riverpod, but the concepts apply to any approach. Ask yourself: "Is this data needed in multiple places?"