The didUpdateWidget()
method in Flutter is called when the parent widget rebuilds and the current widget is updated with new configuration data (i.e., new props or properties). This method is especially useful when you want to respond to changes in the data passed down from a parent widget but do not want to completely rebuild the widget.
Here’s an example that demonstrates the use of didUpdateWidget()
.
Scenario:
Imagine a widget where the color of a container is controlled by the parent widget. The parent can update the color, and we want to change the color of the container in the child widget when that happens.
Example: Using didUpdateWidget()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { Color _containerColor = Colors.blue; // Function to change the color from parent widget void _changeColor() { setState(() { // Change color to red when button is pressed _containerColor = _containerColor == Colors.blue ? Colors.red : Colors.blue; }); } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: Text('didUpdateWidget Example'), ), body: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ // Child widget that depends on the parent's color ColorfulContainer(color: _containerColor), SizedBox(height: 20), ElevatedButton( onPressed: _changeColor, child: Text('Change Color'), ), ], ), ), ); } } // Stateful child widget class ColorfulContainer extends StatefulWidget { final Color color; ColorfulContainer({required this.color}); @override _ColorfulContainerState createState() => _ColorfulContainerState(); } class _ColorfulContainerState extends State<ColorfulContainer> { late Color _currentColor; @override void initState() { super.initState(); // Initialize the color when the widget is first created _currentColor = widget.color; print('initState() called, color: $_currentColor'); } @override void didUpdateWidget(covariant ColorfulContainer oldWidget) { super.didUpdateWidget(oldWidget); // Check if the new color is different from the old one if (widget.color != oldWidget.color) { // If color has changed, update the internal state setState(() { _currentColor = widget.color; }); print('didUpdateWidget() called, color changed to: $_currentColor'); } } @override Widget build(BuildContext context) { print('build() called'); return Center( child: Container( width: 200, height: 200, color: _currentColor, // Display the updated color ), ); } } |
Explanation:
- Parent Widget (
MyApp
):- The parent widget has a state variable
_containerColor
that is either blue or red. - The
ElevatedButton
allows changing the color by calling_changeColor()
, which triggers a rebuild in the parent and passes the updated color to the child widget (ColorfulContainer
).
- The parent widget has a state variable
- Child Widget (
ColorfulContainer
):- The child widget takes the
color
as a property. initState()
is called only once when the child widget is first created, initializing the container’s color.didUpdateWidget()
is triggered when the parent widget passes new data (i.e., when the color changes). It checks whether the new color is different from the old color and updates the internal state if needed.build()
is called to render the container with the new color.
- The child widget takes the
Console Output:
When you first run the app:
1 2 3 |
initState() called, color: Color(0xff2196f3) // Blue build() called |
When you press the Change Color button (the color changes from blue to red):
1 2 3 |
didUpdateWidget() called, color changed to: Color(0xffff0000) // Red build() called |
When you press the Change Color button again (the color changes from red back to blue):
1 2 3 |
didUpdateWidget() called, color changed to: Color(0xff2196f3) // Blue build() called |
Why Use didUpdateWidget()
?
- Efficient Updates: Instead of rebuilding the widget every time data changes,
didUpdateWidget()
allows you to handle changes to specific properties in an efficient way. - State Retention: The widget’s state is preserved, and only the necessary updates (like changing the container’s color) are made without recreating the entire widget.
- Dynamic Parent-Child Communication: If the parent widget passes updated configuration or properties,
didUpdateWidget()
enables the child widget to respond accordingly, updating its internal state or UI.
In this example, didUpdateWidget()
is used to update the container’s color only when the parent provides a new color, making the app more efficient.