Widget TreeEasy20 XP3 min read
Describe the complete lifecycle of a StatefulWidget.
TL;DR: StatefulWidget lifecycle: createState → initState → didChangeDependencies → build → (didUpdateWidget / setState / didChangeDependencies) → deactivate → dispose.
Full Answer
Understanding when each lifecycle method runs is essential for correctly managing resources.
- ▸createState() — called once to create the State object
- ▸initState() — called once when the State is inserted into the tree; safe to init resources
- ▸didChangeDependencies() — called after initState and whenever an InheritedWidget dependency changes
- ▸build() — called to render the widget; may be called many times
- ▸didUpdateWidget(oldWidget) — called when parent rebuilds with a new widget configuration
- ▸setState() — marks the widget dirty, schedules a rebuild
- ▸deactivate() — called when removed from tree (may be re-inserted)
- ▸dispose() — called when permanently removed; clean up controllers, streams, etc.
🎯
Always call dispose() on AnimationController, TextEditingController, ScrollController, and StreamSubscription to avoid memory leaks.
Code Examples
dartFull lifecycle demo
Output
AnimationController is created once, reset when data changes, and disposed when the widget leaves the tree
Common Mistakes
- ✗Forgetting to call super.initState() and super.dispose()
- ✗Calling setState() after dispose() — causes 'setState called after dispose' error
Interview Tip
💡
Interviewers love asking about didUpdateWidget. Explain that it lets you react to parent-driven configuration changes without recreating the State.
#lifecycle#StatefulWidget#initState#dispose#didUpdateWidget