How does flutter update state when it's in the build method versus when it's a field variable

i have a stateless Widget and in it a textfield, now I am storing the onChanged value of the textfield in a variable String? newValue; because it's a stateless widget, I must mark it as final, however, if it's marked final, then I can't use it as a setter, to do,

onChanged: (value) {
  newValue = value;
}  

what I did was I put it in the build() method, so

Widget build(BuildContext context) {
  String? newValue;
return Container();
}  

now I can use it as a setter, OR SO I THOUGHTTTT😠😠😠😠 they tricked meeeee... when i print the value of newValue in the onChanged, it actually is collecting the value, however, when user submits, or clicks away on the keyboard, the value of newValue goes back to the default value which is 'null', When i make the class stateful, i can easily put newValue directly as a field variable, and everything works, it doesn't default to the default value no matter what i do,

so my question is, why does this happen when i store the variable in the build() method, but not when i store it as a class field variable, can someone tell me how this works, why does it default to the initial value and is there anyway to solve it without having to change to a stateful widget and making it a field variable.

Upvotes: 1

Views: 1028

Answers (1)

Michael Horn
Michael Horn

Reputation: 4099

The reason you cannot store state in the build method is that any variable which is declared within a function (or within any block scope) is scoped to that block. So when the build method is called again to re-render your widget, the variable will once again be initialized at the start of the function and will fall out of scope when the function returns, and this will happen on every build.*

This is exactly the problem that StatefulWidget and State<T> solve - by storing the variables as mutable properties on the instance, those variables are available for subsequent calls to build, and are persisted between calls to build.


* In this case the variable is still kind of hanging around, since your onChanged callback is referencing it, and that's why you can still print it; however, its value cannot have any effect on subsequent calls to build.

Upvotes: 1

Related Questions