<div style="width: 30%; margin-left: auto;">

</div>
<a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/"><img alt="Llicència de Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-sa/4.0/88x31.png" /></a><br />Aquesta obra està subjecta a una llicència de <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Reconeixement-CompartirIgual 4.0 Internacional de Creative Commons</a>
# Flutter. Gestió d'estats (01. Provider)
Flutter és un framework que utilitza el paradigma de la [programació declarativa de la UI](https://docs.flutter.dev/data-and-backend/state-mgmt/declarative), que en poques paraules ve a significar que redibuixa tota la interface gràfica a cada canvi d'estat; els canvis d'estat provoquen un rebuild total dels widgets.
Hem vist que podem comunicar dades i events entre diferents widgets enviant paràmetres i callbacks pels contructors dels diferents descendents, però aquest mètode pot arribar a ser una tasca feixuga i difícil de mantenir.
Flutter ofereix una extensa [llista amb diferents aproximacions de com abordar el tema de la gestió dels estats](https://docs.flutter.dev/data-and-backend/state-mgmt/options), en aquesta ocasió ens centrarem a comprendre la classe [__Provider__](https://pub.dev/packages/provider), que com tot a Flutter, és un _widget_.
> Us deixo un enllaç sobre el tema a una xerrada durant la *Google i/o 2019*: [**Pragmatic State Management in Flutter**](https://youtu.be/d_m5csmrf7I?feature=shared).
## El paquet **Provider**
Per començar a utilitzar el paquet Provider a la nostra app, el primer que necessitem fer és declarar-lo al fitxer __pubspec.yaml__, una forma pramàtica de fer-ho és utilitzar la comanda:
```=
$ flutter pub add provider
Resolving dependencies...
collection 1.17.2 (1.18.0 available)
flutter_lints 2.0.3 (3.0.0 available)
lints 2.1.1 (3.0.0 available)
material_color_utilities 0.5.0 (0.8.0 available)
meta 1.9.1 (1.11.0 available)
+ nested 1.0.0
+ provider 6.0.5
stack_trace 1.11.0 (1.11.1 available)
stream_channel 2.1.1 (2.1.2 available)
test_api 0.6.0 (0.6.1 available)
web 0.1.4-beta (0.3.0 available)
Changed 2 dependencies!
```
I ja el podem importar al nostre fitxers main.dart:
import 'package:provider/provider.dart';
Ara ja estem llestos per a utilitzar les classes que ens ofereix el paquet Provider. La primera cosa que farem serà crear el model de l'estat de la nostra aplicació; crearem una nova classe que hereti de ChangeNotifier. En realitat no és estrictament necessari utilitzar ChangeNotifier amb Provider, però ens farà la vida una mica més fácil:
```dart=
import "package:flutter/material.dart";
class LlistaArticles extends ChangeNotifier {
final List<Article> _articles = [];
void afegeix(Article article) {
_articles.add(article);
notifyListeners();
}
void treu(Article article) {
_articles.remove(article);
notifyListeners();
}
Article itemAt(int index) {
return _articles[index];
}
Article getByNom(String nom) {
return _articles.firstWhere((article) => article.nom == nom);
}
int count() {
return _articles.length;
}
}
class Article {
int? id;
String nom = "";
int? quantity = 0;
Article({
required this.id,
required this.nom,
required this.quantity,
});
}
```
A la classe anterior hem incorporat també alguns mètodes que proporcionen utilitats que no modifiquen l'estat i consegüentment no han d'informar als Listeners. Encara falten els mètodes necessaris per incrementar i decrementar les quantitats de cada element.
El Widget proporcionat per Flutter que subministra un ChangeNotifier als seus descendents es diu [**ChangeNotifierProvider**](https://pub.dev/documentation/provider/latest/provider/ChangeNotifierProvider-class.html) i si fem que el nostre node arrel sigui un node d'aquest tipus, tota la nostra app tindrà accés al model que acabem de crear.
A partir d'ara la nostra funció principal quedarà així:
```dart=
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => LlistaArticles(),
child: MyApp(),
),
);
}
```
Arribats a aquest punt, ja no te sentit utilitzar Stateful Widgets a la nostra app, ja que la informació d'estat queda restringida a la classe LlistaArticles que hereta de ChangeNotifier.