How InheritedWidget Fixed My Over-Engineered Flutter App

How InheritedWidget Fixed My Over-Engineered Flutter App

TB

Teqani Blogs

Writer at Teqani

July 23, 20253 min read

Ever used Theme.of(context) or MediaQuery.of(context)?

Yeah… that’s InheritedWidget in disguise.

I used to reach for Provider the moment I needed shared state.

Then one day — mid-debug meltdown — I stumbled onto InheritedWidget. Turns out, the thing I’d been avoiding was the exact tool Flutter had given me all along.

No extra packages. No magic. Just… built-in brilliance.

What Even Is InheritedWidget?

At its core, InheritedWidget is Flutter’s built-in way of sharing data down the widget tree — without passing it through every constructor like it’s a group dinner bill and you’re the only one with a calculator.

It works by:

  • Wrapping part of your widget tree
  • Letting children access data via .of(context)
  • Notifying only the widgets that actually care when something changes

Oh, and here’s the kicker:

Flutter uses this internally all the time to manage state — in Theme, MediaQuery, Navigator, Directionality, and a dozen other places you’ve probably relied on daily.

So yeah… it’s kind of a big deal.

My Overkill Setup (Before Inherited Widget)

  • Installed Provider
  • Made a ChangeNotifier for one string
  • Wrapped everything in MultiProvider (for no reason)
  • Added Consumer widgets like confetti
  • Forgot notifyListeners() constantly

All this… just to update a username.

I basically built NASA’s launch system to show “Hello, Ravi”.

It worked — but felt like delivering a pizza with a rocket.

The InheritedWidget Fix (After)

class UserData extends InheritedWidget {
 final String name;

 const UserData({
 required this.name,
 required Widget child,
 }) : super(child: child);

 static UserData of(BuildContext context) {
 final UserData? result =
 context.dependOnInheritedWidgetOfExactType<UserData>();
 assert(result != null, 'No UserData found in context');
 return result!;
 }

 @override
 bool updateShouldNotify(UserData old) => name != old.name;
}

Use It:

Text(UserData.of(context).name);

That’s it. No drama. No ChangeNotifier. No Provider acrobatics.

Just clean, direct access — like Flutter always wanted it to be.

When to Use It (And When to Run)

Use InheritedWidget when:

  • You need to share data downward (theme, config, state).
  • The data changes infrequently.
  • You want a super lightweight setup.

Avoid if:

  • Your state is async, nested, or complex.
  • You need fine-grained updates across unrelated widgets.
  • You hate updateShouldNotify (though it’s really not that scary).

Honestly, it reminded me of those times you spend 3 hours setting up Bloc, Cubit only to realize:

Dang. I could’ve just used setState() and gone outside.

Sometimes the simplest tools aren’t just enough — they’re better. InheritedWidget is that kind of simple. Like setState(), but for when your widget tree needs to listen without yelling.

So here’s the rule I live by now:

Use InheritedWidget when your data is simple, but needs to be shared across multiple widgets.

No magic. No boilerplate. Just clean, built-in power — the Flutter way.

TB

Teqani Blogs

Verified
Writer at Teqani

Senior Software Engineer with 10 years of experience

July 23, 2025
Teqani Certified

All blogs are certified by our company and reviewed by our specialists
Issue Number: #344dd9ed-8703-4513-93f7-ac743ca14a05