On Flutter, why is the State a Widget itselt? - flutter

I'm getting started with flutter and something doesn't make any sense for me.
I understand the need for StatelessWidget and StatefulWidget. In fact, in React we have the exact same concepts. build in Flutter is render in React and StatelessWidget is a React Functional Component whereas a StatefulWidget is a React.Component. So far, so good.
The problem is that, unlike React, on Flutter, the StatefulWidget is not a Widget that happens to have a state. It is actually just a class that has a createState() that creates a state and, now the part that I don't understand, the State<T> class is the actual Widget because State has build 🤯.
For me, it would make much more sense if the StatefulWidget structure would be like:
class MyApp extends StatelessWidget<TState> {
// Here, the state parameter DOES NOT EXIST. This is pseudo-code.
#override
Widget build(BuildContext context, TState state) {
}
}
This way, the build function creates different Elements based on the current state. This would be much more React like.
Why was Flutter implemented this way? Why is the State class actually the Widget and not the StatefulWidget itself?

Related

How do I implement a version of Flutter's WidgetsBindingObserver without using state?

I am building a flutter app and I need to call a method in a provider when the app goes into background.
I can easily do this by creating a Stateful Widget using the WidgetsBindingObserver (like the example here).
Is there a way to do this without needing a Stateful Widget? Provider is a great architecture and state is an anti-pattern.
Possibly, You could try creating a class that isn't a widget and extending WidgetsBindingObserver.
Something like this perhaps
class MyListener extends WidgetsBindingObserver {
MyListener({this.providerInstance}){
WidgetsBinding.instance.addObserver(this);
};
MyProvider providerInstance;
#override
void didChangeAppLifecycleState(AppLifecycleState state) {
providerInstance.doSomethingWithState(state)
}
}
Then implement the listener say in main() or yourApp() where ever your Provider setup is.
Thing is, there really isn't any issue with having a stateful widget at the root of your app somewhere as in the example. I honestly don't think your Anti pattern argument holds any relevance. Its common practice in flutter to have statefull and not statefull widgets.
By not having the statefull widget your just having to keep the state somewhere else, i.e. where ever it is your configuring your providers.

Flutter stateful widget

class AppWidget extends StatefulWidget {
#override
_AppWidgetState createState() => _AppWidgetState();
}
class _AppWidgetState extends State<AppWidget> {
int _Count = 0;
build(context){}
}
I'm familiar with stateless and stateful widget in flutter but I'm curious why we're not defining stateful widget same as stateless widget? Why we need to declare 2 different class one for createstate method and one for actual state implementation?
I guess may be flutter team use this implementation because when app re-run we can get old state back without losing it if this is the case then How flutter knows?
And if application have more then 1 stateful widget then how flutter manage state for each stateful widget? Again my guess is flutter manage state based on State<AppWidget> but again HOW?
First class is the one that rebuilds the widget if you change anything in it. So for example if you have a text widget in the stateful widget and in the runtime you pressed a button and changed the text from 'Hello World' to 'Hello User' actually what happens is that flutter destroys the second class and rebuild it again with the new text using the first one.
You can find more information in this video from the Flutter Team:
Stateful Widgets Video

Flutter - Is it possible to use BLoC without provider?

class App extends StatefulWidget {
....
return HomeProvider(
homeBloc: HomeBloc(),
child: MaterialApp(
home: HomeScreen(),
),
);
class HomeScreen extends StatefulWidget {
HomeBloc homeBloc = HomeBloc();
}
From the above two scenarios, Most of the tutorials I read, is using the first option. Is the second method completely wrong? or does it have any negative effects in-app?
I can see one difference.
I can access the homeBloc by HomeProvider.of context in the first method. For the second method, I have to pass homeBloc in all the widgets.
Sure, you can use bloc without a provider. But if you share 2 screens with the same bloc, the stream value inside the bloc will be different, because you don't use the InheritedWidget (usually in a provider). The function of a provider is to provide your bloc with InhteritedWidget, so that multiple screens could access to the same stream.
It is definitely possible. I using a single bloc for my entire application right now (as I have come from react-native redux, apollo background, single source of truth makes more sense for me). An example is like below. You can declare your single instance of bloc and import it wherever you use it so you refer to same instance.
class Bloc {
/// Your Bloc Stuff
}
final bloc = Bloc();

Why does a stateful widget build itself using a build method in the state class

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!

What is the reason behind having a StatelessWidget?

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.