I am trying to understand how state and lifting state works in Flutter. In the code below I made a simple app where I tried to pass or lift a string and a function through multiple levels.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String data = 'MyApp class data';
void setTextField(String s) {
setState(
() {
data = s;
},
);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MainApp(data, setTextField),
);
}
}
class MainApp extends StatelessWidget {
final String mainAppData;
final Function setTextField;
MainApp(this.mainAppData, this.setTextField);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(mainAppData)),
body: Container(
child: Level2(mainAppData, setTextField),
),
);
}
}
class Level2 extends StatelessWidget {
final String level2Data;
final Function setTextField;
Level2(this.level2Data, this.setTextField);
@override
Widget build(BuildContext context) {
return Container(
child: Level3(level2Data, setTextField),
);
}
}
class Level3 extends StatefulWidget {
final String level3Data;
final Function setTextField;
Level3(this.level3Data, this.setTextField);
@override
_Level3State createState() {
print('Level3: $this.level3Data');
return _Level3State(this.level3Data, this.setTextField);
}
}
class _Level3State extends State<Level3> {
String level3Data;
Function setTextField;
_Level3State(this.level3Data, this.setTextField);
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
TextField(
onChanged: setTextField,
),
Text(level3Data),
],
);
}
}
When the app starts, the string data
in the _MyAppState
state class is passed to the MainApp
StatelessWidget when MainApp
is built. In a similar manner, info is passed then to Level2
StatelessWidget and Level3
StatefulWidget.
When the TextField
in Level3
changes, setTextField
is triggered. setTextField
is defined up in MyApp
and I figured that when the String data
changes (inside setState()
) it should trigger rebuilding of all the widgets affected by the change.
The text in the MainApp
widget (appBar) changes, showing MainApp
was rebuilt as I expected. But nothing happens to the Level3
widget; it's not rebuilt. The print statement in the createState()
method does not execute, and the Text widget's text does not change.
Why doesn't the Level3
StatefulWidget rebuild?
State
. See stackoverflow.com/questions/50818770/… – Rémi Rousseletwidget
property instead). This should solve your issue – Rémi Rousseletfinal
properties. But the State object's properties can change(?). If you explain what's going on as an answer below I will be happy to accept it. ... Thank you again for the kindness of replying. – Al C