Flutter Vanilla State Management
Tags: architecture, technologyindustrytr, flutter, mobile
Published: 2020-12-07 10:10:14

---
title: Flutter Vanilla State Management
published: true
date: 2020-10-07 15:00:47 UTC
tags: SoftwareArchitecture,Technologyindustrytr,flutter,mobile
canonical_url: https://apiumhub.com/tech-blog-barcelona/flutter-vanilla-state-management/
---

We are all used when managing a state without any library in Flutter we have to create a **StatefulWidget**. And that to change its state and update a widget we have to do it using the **setState(() => state=newState)** method.

However, every time we run **setState** we are rebuilding all the widgets but due to the efficiency with which Flutter rebuilds them, we hardly notice their cost.

In some cases we can minimize the rebuilt widgets by extracting only the widget we want to update in a **StatefulWidget**.

But not in all cases this is possible and in those cases this is achieved with the help of **ValueNotifier** and **ValueListenableBuilder**.

## **ValueNotifier**

**ValueNotifier** is a class that extends **ChangeNotifier** and implements **ValueListenable**.

In the **ChangeNotifier** class all the listener management logic is implemented. You may ask yourself, what are listeners? The listeners are a list of callbacks that are executed when the **notifyListeners** function is called.

So you could say that **ValueNotifier** is a **ChangeNotifier** that keeps a single nullable value that can be of any type and notifies its listeners when this value changes as long as the new value is different from the previous one.

## ValueListenableBuilder

If we want to listen the **ValueNotifier** notifications we need a **ValueListenableBuilder**.

```
class ValueListenableBuilder(
 @required valueListenable: ValueNotifier,
 @required builder: (context, value child) => Widget,
 child: Widget,
)
```

**ValueListenableBuilder** is a **StatefulWidget** that acts as a builder and registers the **setState** method as a listener in the Notifier through the **ValueListenable** interface, thus managing to execute the builder method every time a change of state is notified.

The third child argument is optional, it refers to a widget that we need inside the builder and we want to build only once.

Things to consider:

- The **ValueListenableBuilder** does not manage if the value of the notifier is null or not so if you think that the value can be null you have to control it.
- When the **ValueListenableBuilder** runs the dispose method removed itself from the Notifier listeners.
- It is recommended that we make dispose of the **ValueNotifier** but if we assign a new value after the dispose this will generate a **FlutterError** when running internally **notifyListeners**.

## **Show me the code**

If we take as a reference the counter code that appears when we create a new Flutter project:

```
class _CounterState extends State {
 int _counter = 0;

 @override
 Widget build(BuildContext context) {
   return AppScaffold(
     title: "Stateful Counter",
     children: [
       Text('You have pushed the button this many times:'),
       Text(
         '$_counter',
         style: Theme.of(context).textTheme.headline4,
       )
     ],
     onButtonPressed: () => setState(() => _counter++),
   );
 }
}

```

Implemented with the **Value Notifier** it would look like this:

```
class CounterNotifier extends StatelessWidget {
 final ValueNotifier _counter = ValueNotifier(0);

 @override
 Widget build(BuildContext context) {
   return AppScaffold(
     title: "ValueNotifier Counter",
     children: [
       Text('You have pushed the button this many times:'),
       ValueListenableBuilder(
           valueListenable: _counter,
           builder: (ctx, value, _) {
             return Text(
               '$value',
               style: Theme.of(context).textTheme.headline4,
             );
           })
     ],
     onButtonPressed: () => _counter.value++,
   );
 }
}

```

That’s fine, but what if we have a more complex business logic for the state?

In these cases, you may need to create your own Notifier. You can do this by extending the **ValueNotifier** class. How? Like this:

```
class CustomValueNotifier extends ValueNotifier {
 final SomeRepository repository;
 bool isDispose = false;

 CustomValueNotifier(int initValue, [this.repository = const SomeRepository()]) : super(initValue);

 void increment() async {
   int newValue = await this.repository.increment(value);
   value = newValue;
 }

 @override
 set value(int newValue) {
   if (!isDispose) super.value = newValue;
 }

 @override
 void dispose() {
   isDispose = true;
   super.dispose();
 }
}

```

In this example we are creating a **Value Notifier** to avoid adding a new value after the dispose in the answer of an asynchronous query.

As you can see it’s quite simple. In my opinion one way is not better than the other, it all depends on the context.

 

The post [Flutter Vanilla State Management](https://apiumhub.com/tech-blog-barcelona/flutter-vanilla-state-management/) appeared first on [Apiumhub](https://apiumhub.com).