Like in GetX, we have onInit(), onReady(), onClose() methods inside GetxController.
but in provider which extends ChangeNotifier doesn't have those methods.
so basically i have to use stateful widgets for init's and for other initializations.
So just wanted to know exactly the states of Provider.
Provider does not work as Gets Work. It uses flutter state life cycle.
you can understand like that:
Initialise provider at Starting of App
Create a class which extends Change Notifier
To fetch value- create instance of provider or use Consumer at You Widget
For Better understanding you can follow this Link:https://github.com/Code-With-Patel/Provider.git
Related
I have a Stateful widget that uses the setState method in one of its class methods. I want to convert that widget into an ordinary class so I can use it in Object Oriented Programming. I want to instantiate an instance of that class in another stateful widget and access the methods that have the setState method in them. But I am currently getting this error "The method 'setState' isn't defined for the type 'MyClass'. Try correcting the name to the name of an existing method, or defining a method named 'setState'."
How can I do this?
The setState method is linked to the state of a stateful Widget. If you want to convert your widget to a Class you can't use setState in it. But you can give the Class a Function as parameter. Anytime you instantiate this Class in a stateful Widget just give the setState from this stateful Widget to the class.
I think you need to add a better state management solution to your code than stateful widget ,maybe riverpod,
Using riverpod you can access the same notifier from other widgets and thus the setState functionality plus it has the added benefit of splitting the logic and ui into an mvvm like pattern
setState only exists for the StatefulWidget. You cannot call setState in the class without extending a StatefulWidget. So if you want to do that you can use a state management plugin in the Flutter like Provider, Bloc or Getx.
I am new to flutter, I wonder why we extend Statefull or stateless classes to create our own widgets, why not creating the objects of the instead. Now many others might say it has build function that needs to be overridden but I guess it can also be done inside the object. Please give me an explanation.
flutter has lifecycle, widget will appear after build
https://i.stack.imgur.com/94idE.png
Both Stateful and Stateless classes are abstracts.
So that, to use methods such as initState in Stateful or "build" in both kind of widgets you need extend either Stateful or Stateless (exactly "extends" keyword, if you use "implements" keyword, you will be forced to implement all of the methods described in abstract).
More about:
StatefulWidget
StatelessWidget
The official Mobx documentation for Flutter says that in order to transfer data correctly, you must use a Provider and refer to the context to retrieve the data.
But why can't I just call the Mobx class at the root of the application and access the global variable to get the data?
CbtStore cbt = CbtStore();
void main() async {
runApp(const MyApp());
}
Why should I be doing this?
void main() async {
runApp(MultiProvider(
providers: [
Provider<CbtStore>(create: (_) => CbtStore()),
],
child: MyApp()));
}
And how do I refer to Mobx inside the widget methods in that case, for example, if I want to call the action in the Mobx class in initState method? Now I do it in the following way. But when using Provider in initState there is no context.
#override
void initState() {
cbt.init();
super.initState();
}
Provider is used only for dependency injection with mobx. It is not used for state changes.
Now when you are using mobx you don't need a stateful widget in most cases because you are handling your state changes inside your mobx store and if there is any changes in the state we use Observer to change ui.
if want something to initialise with the screen than prefer using constructor of mobx class rather then initState.
for example,
class MyStore = _MyStore with _$MyStore;
abstract class _MyStore with Store {
_MyStore(){
getData();
}
}
Now don't use global providers for your all of store. Only Initialise a provider whenever you need it. So when you push a route wrap it with a provider so that Provider.of(context); can find it. Only use global store if it required globally.
You mentioned creating an instance of store to use it. When you initialise a store in stateless widget it, the data will get destroyed when you close the screen and when you reopen it everything will start all over again. It is useful when you don't need to maintain state after screen pops. It will based on your use case.
You should do what works best for your use case.
The reason why providers are useful is that they can be provided where needed. This could be in the application root, but also somewhere deeper in the widget tree.
Another advantage of the providers is that you can have a provider that notifies listeners. Widgets will rebuild automatically in this case, which can be useful if you have stored and need data to update everywhere in the application.
The initState does indeed not allow the use of providers directly. There are 3 solutions for this:
Don't have the provider listing (Provider.of(context, listen: false); This allows you to use the methods, but not listen to changes.
Use the provider in the build method, using the consumer.
I am by no means an expert on flutter, but this is just what I have experienced so far.
In one of my projects, I am using flutter_bloc package.
In that example, I instantiated bloc inside didChangeDependencies(). So bloc lives during the lifecycle of a screen.
However, my colleague told me not to initialize there. He said bloc should be initialized in app.dart where It can live over the lifecycle of the app. Because, in cases where there should be multiple screens on tablet, it will break the code.
For example, I have ScreenA, ScreenB and ScreenC. you can go to ScreenB and ScreenC through ScreenA. ScreenB and ScreenC use the same bloc, and bloc is initialized sepearately in each screens. He is saying that if the requirement is to show ScreenB and ScreenC simultaneously on a tablet, it might break the code. How?
Could you suggest me what is best? Or does it depend on the usecase?
It is the best practice to initiate bloc instance during initState as it runs only once per widget lifecycle. didChangeDependencies() may be called multiple times for example if widget is moved in the widget tree or widget gets notified of InheritedWidget change, so bloc will get new instance like that and you dont want that. What your collegue is talking is more about BlocProviders scope and sure is normal practice, but for some small-usecase-bloc might be redundant. That is up to you to decide does your whole app needs to be in scope of this bloc. Keep in mind that if lazy property is not set to false, your bloc will be created with the first call to it.
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.