Problem: build() depends in StatefulWidget's state
Recently I moved a property inspector widget from being an always visible part of the UI to a Drawer.
Once I moved the property inspector, the app rendered random update operations regarding the object when the property inspector was about to edit values: The property inspector updated a random other object, not the current 'focus' object.
Solution : Make build() depend on the State<T> of StatefulWidget
I solved the issue by making the State<PropertyInspector> solely depend on state variables defined inside State<PropertyInspector> itself - instead of defining state variables in StatefulWidget and accessing these variables using widget.<someVariable>.
Root cause of the problem seems to be the fact that the Property Inspector in the Drawer gets more updates from the framework than the permanently visible alternative.
General advice
In general, Flutter needs to insert / remove / update StatefulWidget at various moments of time. While StatefulWidget might change, its State<T> object persists.
Thus, the build() method of a StatefulWidget should depend on State<T> - and not on the changing StatefulWidget.
Rules of thumb
StatefulWidget should be finalStatefulWidget can't be marked as final, the design of the StatefulWidget is wrong.State<T>, access to 'widget.*' instance variables are fine, as long as those variables are final.State<T> may be non-finalIs my description correct?
This site doesn't warn about using state as widget.*. Isn't that wrong? or at least dangerous / bad style?
As far as I understand, the proposed state in StatefulWidget might work fine for some time. But, under different conditions, it is likely to render problems (as mine).
Helpful video How Stateful Widgets Are Used Best - Flutter Widgets 101 Ep. 2 in Flutter's StatefulWidget class documentation.
Contradiction
This lint error contradicts my explanation: no_logic_in_create_state
I'd be happy if answers would explain, if this description / practice is correct or not.
I established this practice since certain widgets didn't behave as expected in some projects.
If I have understood your description properly then I would say your rules of thumb are correct. The state class and fields persist across renders, therefore any mutable state should be enclosed within the state class not within the widget class.
The lint no_logic_in_create_state doesn't contradict this, the lint is saying no logic in the create state method, which is in the widget class.
Any mutable field in the widget class could be reset when the widget re-renders and therefore no mutable state should be kept in any widget.
I will also add that just because an instance variable in a widget is final doesn't mean it wont change within the lifecycle of the app. If you pass a prop into the widget then the instance variable would update if the prop updates (the widget would be recreated but the state wouldn't).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With