I looked at Riverpod's counter example and noticed it uses ConsumerWidget instead of ConsumerStatefulWidget.
If ConsumerWidget can show state changes, is there any need to use ConsumerStatefulWidget? Why Riverpod, as a state management solution, has both stateful and stateless consumer widgets? It seems there is something I haven't yet comprehend
ConsumerStatefulWidget is here for if you want local state in your widget. Like instantiating an AnimationController
Typically providers are for shared state. But they don't deal with local state.
Hence why you still sometimes need Statefulwidgets (or flutter_hooks if that's your thing)
I'll also add that we can quickly enough replace StatefulWidget with ConsumerStatefulWidget (and State with ConsumerState) to access the ref variable throughout the widget. This is very useful when we have a previously written complex StatefulWidget widget with lots of controllers (well, just imagine!) and suddenly we need to access ref and use Riverpod to its full potential.
Then it becomes obvious and looks amazing!
Afterword: later on you will also find out that ConsumerWidget is actually a ConsumerStatefulWidget :)
Related
I just started learning Flutter and as a beginner I'm facing some issues about understanding a state. I watched some videos on YouTube, read articles online. They explain the reason why one should use a Stateful Widget instead of Stateless. But I can't really understand what part of an app needs to be a Stateful Widget and what the use of the setState method is. Also what's the difference between the state of a widget and state of the app?
Flutter is declarative. This means that Flutter builds its user interface to reflect the current state of your app:
State can be described as "whatever data you need in order to rebuild your UI at any moment in time".
When the state of your app changes (for example, the user flips a switch in the settings screen), you change the state, and that triggers a redraw of the user interface.
There is no imperative changing of the UI itself (like widget.setText)—you change the state, and the UI rebuilds from scratch.
The state that you do manage yourself can be separated into two conceptual types: ephemeral(widget state on your question) state and app state.
Ephemeral state
Ephemeral state (sometimes called UI state or local state) is the state you can neatly contain in a single widget.
There is no need to use state management techniques (ScopedModel, Redux, Provider, bloc, etc.) on this kind of state. All you need is a StatefulWidget.
You only need to use setState to alter your current state.
For example, below, you see how the currently selected item in a bottom navigation bar is held in the _index field of the _MyHomepageState class.
In this example, _index is ephemeral state.
class MyHomepage extends StatefulWidget {
const MyHomepage({Key? key}) : super(key: key);
#override
_MyHomepageState createState() => _MyHomepageState();
}
class _MyHomepageState extends State<MyHomepage> {
int _index = 0;
#override
Widget build(BuildContext context) {
return BottomNavigationBar(
currentIndex: _index,
onTap: (newIndex) {
setState(() {
_index = newIndex;
});
},
// ... items ...
);
}
}
Here, using setState() and a field inside the StatefulWidget’s State class is completely natural. No other part of your app needs to access _index.
The variable only changes inside the MyHomepage widget. And, if the user closes and restarts the app, you don’t mind that _index resets to zero.
App state
State that is not ephemeral, that you want to share across many parts of your app, and that you want to keep between user sessions, is what we call application state (sometimes also called shared state).
Examples of application state:
User preferences
Login info
Notifications in a social networking app
The shopping cart in an e-commerce app
Read/unread state of articles in a news app
For managing app state, you’ll want to research your options. Your choice depends on the complexity and nature of your app, your team’s previous experience, and many other aspects.
Here's a link to an example on app wide state management using provider(one of many state management libraries), Example.
Here's a list of libraries that are used for app wide state management, Options.
In summary, there are two conceptual types of state in any Flutter app. Ephemeral state can be implemented using State and setState(), and is often local to a single widget. The rest is your app state.
Both types have their place in any Flutter app, and the split between the two depends on your own preference and the complexity of the app.
In the Stateless widget, the build function is called only once which makes the UI of the screen. It means through that widget you cannot change the UI again. It will render(build) the UI at once. So for those widgets, you need to send the information before building the widget.
Stateful Widgets: The widgets whose state can be altered once they are built are called stateful Widgets. This simply means the state of an app can change multiple times with different sets of variables, inputs, data. Below is the basic structure of a stateful widget. That means you can change the UI of this widget without building it again with help of the setState method.
For more information refer - https://medium.com/flutter-community/flutter-stateful-vs-stateless-db325309deae
if we want to make changes in our UI so that we use statefulWidget
otherwise we use statelessWidget.
in most case we will be using statefulWidget.
that's it.
https://flutter.dev/docs/cookbook/effects/photo-filter-carousel#interactive-example
I have a question about the sample at the end of the above page.
However, the question itself has little to do with the subject matter on the above page.
ExampleInstagramFilterSelection is a subclass of StatefulWidget.
State management seems to be done with ValueNotifier + ValueListenableBuilder.
Looking at the code, I thought that ExampleInstagramFilterSelection could be a Stateless Widget, so I tried making it a Stateless Widget and tried it.
There is no particular error, and it looks exactly the same as before the change.
I can't think of the reason why ExampleInstagramFilterSelection is (a subclass of) StatefulWidget like the sample (why it's better to make it a subclass of StatefulWidget). Is there anything?
I can only think of "We might need State in the future", but then I feel like we should just make it a StatefulWidget when we need it.
You are correct, the ExampleInstagramFilterSelection in the above example could be simplified by converting it into a StatelessWidget.
As it is, there is no need to use a StatefulWidget, because the Widget does not need to redraw itself because of a changed member.
All the state handling is done in FilterSelector.
I get the general idea that the StatefulWidget my get rebuild very often, and even get assigned to a different State if not using key in some cases. However the State of that widget always exists in memory. I need to change some data of the State when it's not shown. Is it safe to keep the reference of that State instance for example in a singleton and change its data?
Specifically, I have a StatefulWidget(call it homapage) with PageView. Its State keeps the reference of the PageController. I want to change the controller.page when the screen is showing other tabs rather than homepage. I did this via keeping a reference of the State in a singleton. In order to do it, I need to make the State class public by deleting the _ in front of the State class name. If feels unsafe and against the Flutter design philosophy to me.
The state will be destroyed when a widget that uses that state is no longer in the widget tree. We recommend that you use GlobalKey and don't use a singleton as a reference to the State. Using InheritedWidget is also a good option.
I'm just learning flutter - I build a few basic tutorials and am now trying to build a simple notepad application.
https://github.com/sketchbuch/examples_flutter/blob/master/notes/lib/src/components/notepad/notepad.dart
In this file I have a stateful widget which has a state property. What I don't understand is why I need the stateful widget at all... the state class seems to be doing everything including building the list of notes.
Am I doing this right? It doesn't seem right that state builds the whole stateful widget...maybe it is just because my app is basic at the moment but the stateful widget doesn't seem to do anything at the moment.
I just would have thought that the staefulwidget would handle rendering and state would just be an object storing properties
As pointless as an empty StatefulWidget subclass looks like, it is necessary. That class is what allows Flutter to manipulate the State subclass.
Without a StatefulWidget, Flutter is unable to create/update/dispose of a State.
StatefulWidget subclass is also a way to customize the behavior of State by adding fields in StatefulWidget and using them in the State class.
You're saying
My Notepad widget as such is not doing anything but my _NotepadState is. Then why should I use the redundant Notepad widget?
Why is it required?
Your Notepad widget is not alone. It has super classes. It extends StatefulWidget which in turn extends Widget (which extends DiagnosticableTree which extends Diagnosticable).
The super classes are doing all the heavy lifting for you and that you had to write almost zero code. Mostly it is used to accept parameters and create state.
Hope that helps!
I have noticed that, we can use a StatefulWidgetto build any part of the UI without worrying about the state.
What I am asking is simply, what are the reasons behind having a StatelessWidget in the first place, when we can build any UI class as a StatefulWidget whether we are going to provide it with a State or not?
Does using a StatefulWidget comes with an additional cost that makes creating a stateless UI easier/faster/better using a StatelessWidget?
When I read the docs, I can not exactly point out the difference between using StatelessWidget and StatefulWidget when describing stateless UI components. It is even recommended to
Consider refactoring the stateless widget into a stateful widget so
that it can use some of the techniques described at StatefulWidget...
If your widget manages state, you should use a StatefulWidget with an associated State object to store the state.
If your widget doesn't manage any state, and its build method only depends on its constructor arguments (or Inherited widgets such as Theme), it's better to use a StatelessWidget. StatelessWidget requires defining fewer classes and invoking fewer methods, so it should be faster and more maintainable than an equivalent StatefulWidget that doesn't cache anything in its state.
If you follow the Push the state to the leaves performance optimization, you will be changing a StatefulWidget to a StatelessWidget and factoring out the stateful parts into a simpler StatefulWidget (which may take a child argument and cache it). This pattern adds more classes but has the benefit of reducing the amount of work necessary when the state changes.