It stays at 0 because the call to setState()
you are doing will update the state of _ChildPageState
and not the state of your body: ParentPage()
as it is a different instance.
Same goes for your print('build[$counter]');
it will display the correct value because it is the counter
variable of your _ChildPageState
and not the one from your ParentPage()
.
Edit:
_ChildPageState
by extending your ParentPageState<ChildPage>
has a counter
variable and an incrementCounter()
method.
The same goes for body: ParentPage()
, as it is a new instance of ParentPage
it has its own counter
and incrementCounter()
.
By calling incrementCounter
in your code like this:
class _ChildPageState extends ParentPageState<ChildPage> {
@override
Widget build(BuildContext context) {
// ...
return Scaffold(
// ...
floatingActionButton: FloatingActionButton(
onPressed: incrementCounter, // Here
child: Icon(Icons.add),
),
);
}
}
You are refering to the incrementCounter
method from your _ChildPageState
to increment the counter
value of _ChildPageState
. This is why print('build[$counter]');
updates itself correctly as it is the counter
from _ChildPageState
.
Now for your body: ParentPage()
, as I've said, it has its own properties and methods, which means that its method incrementCounter
is never called and its counter
value will never be incremented.
Example
Code
class ParentPage extends StatefulWidget {
final String pageId;
const ParentPage({required this.pageId});
@override
ParentPageState createState() => ParentPageState();
}
class ParentPageState<T extends ParentPage> extends State<T> {
int counter = 0;
void incrementCounter() {
print('Update counter from: ${widget.pageId}');
setState(() => counter++);
}
@override
Widget build(BuildContext context) => Text('$counter'); // Not updating
}
class ChildPage extends ParentPage {
const ChildPage() : super(pageId: 'ChildPage');
@override
_ChildPageState createState() => _ChildPageState();
}
class _ChildPageState extends ParentPageState<ChildPage> {
@override
Widget build(BuildContext context) {
print('build[$counter]'); // Updates
return Scaffold(
body: const ParentPage(pageId: 'Body Page'),
floatingActionButton: FloatingActionButton(
onPressed: incrementCounter,
child: const Icon(Icons.add),
),
);
}
}
Output
build[0]
Update counter from: ChildPage // First Tap
build[1]
Update counter from: ChildPage // Second Tap
build[2]
As you can see the incrementCounter
from ParentPage(pageId: 'Body Page')
is never called to increment its counter
.
Try the example on DartPad