DidChangeDependencies and DidUpdateWidget in Flutter
What are these similar-looking Flutter Lifecycle callbacks?

FLUTTER
DidChangeDependencies and DidUpdateWidget in Flutter
If you’ve been around Flutter long enough to dive into the StatefulWidget lifecycle, you’ve probably seen two eerily similar methods: didChangeDependencies and didUpdateWidget.
They sound like they do the same thing.
They’re both lifecycle callbacks.
And they both seem to react to “something changing.”
But here’s the twist: they don’t fire for the same reasons. And mixing them up can lead to unnecessary rebuilds or even confusing bugs.
Let’s break this down — not as another dry documentation dump, but as a story of when, why, and how these two callbacks come into play.
First: Why do lifecycle methods even exist?
Flutter’s rendering system is declarative. That means your widget tree reacts to state, not imperative calls. So when something changes — like a theme, a localisation setting, or a parent rebuild — you sometimes need to respond.
And that’s where lifecycle callbacks come in.
Meet didChangeDependencies: the Context Listener
Think of didChangeDependencies as your go-to place for reacting to changes in inherited widgets.
It runs:
• After initState (once)
• Whenever an InheritedWidget it depends on changes
Common use case:
@override
void didChangeDependencies() {
super.didChangeDependencies();
final locale = Localizations.localeOf(context);
print('Locale changed: $locale');
}
So if the app’s locale changes (say, English to Spanish), your widget can react accordingly — maybe reload some data or update labels.
Gotcha:
It gets called more often than you expect, especially if your widget depends on inherited widgets like Theme, MediaQuery, Localisations, etc.
So don’t put expensive logic here unless you memoise or debounce it.
Now, meet didUpdateWidget: the Props Comparator
This one’s more specific. It’s called only when the widget is rebuilt with a new configuration, but the same runtime type and still mounted in the tree.
It runs:
• Whenever the Widget is updated (i.e. build() is called again)
• But only if the parent passed in a new widget with different fields
Common use case:
@override
void didUpdateWidget(covariant MyWidget oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.userId != oldWidget.userId) {
_loadUser(widget.userId);
}
}
This is useful if your widget receives props (such as userId) from its parent and the parent rebuilds it with new values.
didUpdateWidget lets you respond to those changes without needing to dispose of and recreate the widget.
TL;DR: Who listens to what?

Real-world analogy
Imagine you’re an employee at a company.
• didChangeDependencies is like HR emailing that the company policy has changed. You need to re-read it and possibly adjust your approach.
• didUpdateWidget is your manager changing your role or project. You’re still employed, still in the org chart — but with a new focus.
Should I use both?
Sometimes, yes.
Let’s say you’re building a widget that:
- Takes the userId as a parameter from its parent
- Also depends on Theme.of(context) for styling
Then you’d likely use:
- didUpdateWidget to fetch data when the userId changes
- didChangeDependencies to update styles or re-render when the theme changes
Keeping their responsibilities separate keeps your logic clean and avoids over-rebuilding.
One last thing…
Don’t forget that didChangeDependencies is always called after initState. So if you’re initialising something that depends on context (like inherited widgets), don’t do it in initState — use didChangeDependencies instead.
@override
void initState() {
super.initState();
// DON’T access Theme.of(context) here
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
final theme = Theme.of(context); // YES
}
Final takeaway
In Flutter, lifecycle callbacks aren’t just technical details — they’re powerful tools when used right. But using the wrong one in the wrong place? That’s a subtle trap.
So next time you’re wiring up a StatefulWidget, pause for a second.
Ask yourself:
Am I reacting to context? Or to new props?
Let that answer guide you to either didChangeDependencies or didUpdateWidget.