[{"data":1,"prerenderedAt":68},["ShallowReactive",2],{"tutorial-gestire-lo-stato-in-flutter-con-provider-guida-pratica":3,"comments-tutorial-gestire-lo-stato-in-flutter-con-provider-guida-pratica":67},{"id":4,"title":5,"slug":6,"excerpt":7,"intro":8,"cover_image":9,"video_url":10,"difficulty":11,"estimated_minutes":12,"flutter_version":13,"status":14,"published_at":15,"meta_title":16,"meta_description":17,"category":18,"author":22,"steps":24},2,"Gestire lo stato in Flutter con Provider: guida pratica","gestire-lo-stato-in-flutter-con-provider-guida-pratica","Impara a usare il pacchetto Provider per gestire lo stato della tua app Flutter in modo pulito e scalabile, separando la logica dalla UI.","## Introduzione\n\nLa gestione dello stato è uno degli aspetti più importanti (e a volte confusi) nello sviluppo con Flutter. Quando la nostra app cresce, usare solo `setState` diventa difficile da mantenere e poco scalabile.\n\nIn questo tutorial impareremo a usare **Provider**, una delle soluzioni di state management più popolari e raccomandate dal team di Flutter. Costruiremo un semplice contatore e una lista della spesa per mostrare come condividere e aggiornare lo stato tra widget diversi senza passare manualmente i dati attraverso i costruttori.\n\nAl termine avrai una base solida per applicare Provider nei tuoi progetti reali.","https:\u002F\u002Fflutter.it\u002Fstorage\u002Ftutorials\u002F87c1d826-332c-4f8f-9756-5bea88de86b3.jpg",null,"intermediate",35,"3.x","published","2026-06-08T10:14:54+00:00","Gestire lo stato in Flutter con Provider","Guida pratica a Provider in Flutter: crea un ChangeNotifier, registralo e aggiorna la UI in modo reattivo e scalabile. Esempi di codice inclusi.",{"id":19,"name":20,"slug":21},1,"Guide","guide",{"id":19,"name":23},"Flutter Bot",[25,32,39,46,53,60],{"id":26,"position":19,"title":27,"body":28,"code_snippet":29,"code_language":30,"expected_result":31,"demo_url":10,"video_url":10},13,"Aggiungere la dipendenza Provider","Per prima cosa aggiungiamo il pacchetto `provider` al nostro progetto. Apri il file `pubspec.yaml` e inseriscilo nella sezione `dependencies`, oppure usa il comando da terminale.\n\nDopo aver aggiunto la dipendenza, esegui `flutter pub get` per scaricarla (il comando da terminale lo fa automaticamente).","# Da terminale, nella cartella del progetto\nflutter pub add provider\n\n# Oppure manualmente in pubspec.yaml\ndependencies:\n  flutter:\n    sdk: flutter\n  provider: ^6.1.2","yaml","Il pacchetto provider viene scaricato e diventa disponibile per l'import nel progetto.",{"id":33,"position":4,"title":34,"body":35,"code_snippet":36,"code_language":37,"expected_result":38,"demo_url":10,"video_url":10},14,"Creare il modello con ChangeNotifier","Il cuore di Provider è la classe che contiene lo stato. Creiamo un file `counter_model.dart` con una classe che estende `ChangeNotifier`.\n\nIl metodo `notifyListeners()` è fondamentale: ogni volta che lo chiamiamo, tutti i widget in ascolto verranno ricostruiti con i nuovi dati.","import 'package:flutter\u002Ffoundation.dart';\n\nclass CounterModel extends ChangeNotifier {\n  int _count = 0;\n\n  int get count => _count;\n\n  void increment() {\n    _count++;\n    notifyListeners(); \u002F\u002F notifica i widget in ascolto\n  }\n\n  void decrement() {\n    if (_count > 0) {\n      _count--;\n      notifyListeners();\n    }\n  }\n\n  void reset() {\n    _count = 0;\n    notifyListeners();\n  }\n}","dart","Hai una classe CounterModel che incapsula lo stato e notifica i cambiamenti.",{"id":40,"position":41,"title":42,"body":43,"code_snippet":44,"code_language":37,"expected_result":45,"demo_url":10,"video_url":10},15,3,"Registrare il Provider nell'albero dei widget","Per rendere il modello accessibile ai widget, dobbiamo registrarlo in alto nell'albero. Usiamo `ChangeNotifierProvider` avvolgendo il widget radice (`MyApp`) nel `main`.\n\nIn questo modo qualsiasi widget figlio potrà accedere all'istanza di `CounterModel`.","import 'package:flutter\u002Fmaterial.dart';\nimport 'package:provider\u002Fprovider.dart';\nimport 'counter_model.dart';\n\nvoid main() {\n  runApp(\n    ChangeNotifierProvider(\n      create: (context) => CounterModel(),\n      child: const MyApp(),\n    ),\n  );\n}\n\nclass MyApp extends StatelessWidget {\n  const MyApp({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      title: 'Provider Demo',\n      theme: ThemeData(primarySwatch: Colors.blue),\n      home: const CounterPage(),\n    );\n  }\n}","L'istanza di CounterModel è ora disponibile per tutti i widget discendenti di MyApp.",{"id":47,"position":48,"title":49,"body":50,"code_snippet":51,"code_language":37,"expected_result":52,"demo_url":10,"video_url":10},16,4,"Leggere lo stato con Consumer","Ora costruiamo la pagina che mostra il contatore. Usiamo il widget `Consumer\u003CCounterModel>` per ascoltare i cambiamenti: solo la parte avvolta dal `Consumer` verrà ricostruita quando lo stato cambia, ottimizzando le prestazioni.\n\nIn alternativa a `Consumer`, puoi usare `context.watch\u003CCounterModel>()` direttamente nel metodo build.","class CounterPage extends StatelessWidget {\n  const CounterPage({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(title: const Text('Contatore con Provider')),\n      body: Center(\n        child: Column(\n          mainAxisAlignment: MainAxisAlignment.center,\n          children: [\n            const Text('Valore attuale:'),\n            Consumer\u003CCounterModel>(\n              builder: (context, model, child) {\n                return Text(\n                  '${model.count}',\n                  style: const TextStyle(fontSize: 48),\n                );\n              },\n            ),\n          ],\n        ),\n      ),\n    );\n  }\n}","La pagina mostra il valore del contatore, che si aggiornerà automaticamente quando cambia.",{"id":54,"position":55,"title":56,"body":57,"code_snippet":58,"code_language":37,"expected_result":59,"demo_url":10,"video_url":10},17,5,"Modificare lo stato con context.read","Per modificare lo stato senza ascoltarlo (ad esempio dentro un `onPressed`), usiamo `context.read\u003CCounterModel>()`. È importante usare `read` e non `watch` nei callback, perché non vogliamo ricostruire il widget ma solo invocare un metodo.\n\nAggiungiamo dei pulsanti per incrementare, decrementare e azzerare il contatore.","floatingActionButton: Column(\n  mainAxisAlignment: MainAxisAlignment.end,\n  children: [\n    FloatingActionButton(\n      heroTag: 'inc',\n      onPressed: () => context.read\u003CCounterModel>().increment(),\n      child: const Icon(Icons.add),\n    ),\n    const SizedBox(height: 12),\n    FloatingActionButton(\n      heroTag: 'dec',\n      onPressed: () => context.read\u003CCounterModel>().decrement(),\n      child: const Icon(Icons.remove),\n    ),\n    const SizedBox(height: 12),\n    FloatingActionButton(\n      heroTag: 'reset',\n      onPressed: () => context.read\u003CCounterModel>().reset(),\n      child: const Icon(Icons.refresh),\n    ),\n  ],\n),","Premendo i pulsanti il contatore aumenta, diminuisce o si azzera, e la UI si aggiorna in tempo reale.",{"id":61,"position":62,"title":63,"body":64,"code_snippet":65,"code_language":37,"expected_result":66,"demo_url":10,"video_url":10},18,6,"Ottimizzare con Selector e best practice","Quando il modello contiene molti dati, ricostruire tutto a ogni `notifyListeners()` può essere inefficiente. Il widget `Selector` permette di ascoltare solo una parte specifica dello stato, ricostruendo la UI solo quando quel valore cambia.\n\n**Best practice utili:**\n- Usa `context.read` nei callback, `context.watch` o `Consumer` nel `build`.\n- Mantieni i modelli piccoli e focalizzati su una responsabilità.\n- Usa `Selector` per ottimizzare widget costosi.\n- Se ti servono più modelli, usa `MultiProvider`.","\u002F\u002F Esempio con Selector: ricostruisce solo se 'count' è pari\nSelector\u003CCounterModel, bool>(\n  selector: (context, model) => model.count.isEven,\n  builder: (context, isEven, child) {\n    return Text(isEven ? 'Pari' : 'Dispari');\n  },\n)\n\n\u002F\u002F Esempio con piu' provider\nMultiProvider(\n  providers: [\n    ChangeNotifierProvider(create: (_) => CounterModel()),\n    ChangeNotifierProvider(create: (_) => CartModel()),\n  ],\n  child: const MyApp(),\n)","La tua app gestisce lo stato in modo efficiente e scalabile, ricostruendo solo i widget necessari.",[],1781247857919]