DEV Community

Cover image for Providers and Stateless widget
Prakash S
Prakash S

Posted on

Providers and Stateless widget

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'

pubspec.yaml-provider

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

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)