As we all know Stateless widget won't change for any state changes. But There is some technique that we can use to update the stateless widgets..
With the help of Streams we can do it easily. But unwiring streams in Stateless widget is hell!!!😡😡
Thanks to the package 'Provider'
Yes, Using provider we can update the Stateless widget UI also we can dispose the streams and other disposable objects.
Provider is really helpful to start to do 'Separation of concerns' in flutter.
We can isolate our business logics & UI, which makes our app easily testable and reusable
Lets stop here and jump into the code
Add the provider package in 'pubspec.yaml'
Let us create a stateless widget which has Text, TextField, RaisedButton and a Container
Our idea is simple that when any text changes in TextField my Text widget should reflect the change, similarly whenever we press the Button the Container color should change.
In this post, I am going to do it in two ways
1) ChangeNotifierProvider
2) Provider & Streams
Folder Structure
ChangeNotifierProvider
The name tells what we are going to do. Yes we are going to notify the changes and reacts to those changes.
We have a base model 'MyModelBase' which has 'myText' & 'isValid' property
Now we have our Notify model 'MyNotifierModel' which inherits from our base model also with a mixin called 'ChangeNotifier'
We are now going to override our setter of myText & isValid and invoking 'notifylistener' method. After this our model will look like the below.
Now our model is ready to notify the changes!!! Hurray!!!
But how this changes are going to affect our widget 😞
Thanks to 'ChangeNotifierProvider' & 'Consumer' widget 😇
ChangeNotifierProvider has
1) 'create' method by which we are initiating our model
2) 'child' property by which we are adding our UI.
Here we are using 'Consumer' widget as child to listen the notification from our model.
Once the notifylistener called in the model our Consumer will trigger to rebuild.
As Consumer widget provides the model as param which has the updated value, we can simply bind to the corresponding UI.
Now you may notice that the action of RaisedButton and TextField are independent, means both actions are impacting different elements like TextField impacts the Text widget and RaisedButton impacts the Container.
But the Consumer widgets rebuilding all the four elements instead for the corresponding changes. Yes, notifylistener is called for full model not for the properties.
Lets see how Provider & Streams can solve this problem.
Provider & Streams
We are going to have a model called 'MySimpleModel' which inherits from BaseModel, So we override the setText & setIsValid.
Along with this, we are going to have StreamController for text and boolean.
Of course we are closing the stream in a dispose method.
Our model will look like as below
Now, we are going to use the Provider which has
1) 'create' - used to instantiate our model
2) 'dispose' - clears any reference for the model
While constructing Text & Container widget, we are wrapping those into a 'StreamBuilder' and takes the text and boolean stream correspondingly
As we are adding the changes to the stream controller in our model, our stream builder re-build the UI as per the corresponding stream
More importantly we are 'disposing/closing' our stream with the help of Provider's dispose callback
How sweet it is 😊😊
UI Widget will look like:
for full sample please find in the Github repo link
Happy fluterring 😇😇!!
Top comments (0)