{"id":2634,"date":"2019-12-26T12:04:05","date_gmt":"2019-12-26T12:04:05","guid":{"rendered":"https:\/\/eluminoustechnologies.com\/blog\/?p=2634"},"modified":"2025-10-08T10:33:19","modified_gmt":"2025-10-08T10:33:19","slug":"reactive-app-with-flutter","status":"publish","type":"post","link":"https:\/\/eluminoustechnologies.com\/blog\/reactive-app-with-flutter\/","title":{"rendered":"How to Use BLoC to Build a Reactive App with Flutter"},"content":{"rendered":"<p>Flutter, since its debut in May 2017, has grown by leaps and bounds as a mobile app development framework. Google has consistently released improved iterations of the framework that have not only made developing mobile apps easier but also faster and more cost-effective.<\/p>\n<p>The search-engine giant introduced another major update at I\/O 2018 \u2013 the ability to <a href=\"https:\/\/eluminoustechnologies.com\/hire-developers\/flutter\/\" target=\"_blank\" rel=\"noopener\">build reactive mobile apps with Flutter<\/a>. So, what is a reactive app and how has Flutter made it easier to develop such an app? Read on to know more.<\/p>\n<div class=\"blue-bg-box-small text-align-center mb-4\"><em>What are Reactive Mobile Apps?<\/em><\/div>\n<p>All of us use reactive apps in our daily lives. Examples include your email and weather apps or the app you use to check out which movies are playing at your local theatre.<\/p>\n<p>A reactive app is one that responds to your actions and needs with a standard set of behaviors. Examples of these responses include reflecting changes in the UI instantaneously, syncing information across multiple devices based upon user inputs (data updates, push notifications, scheduling etc.) and updating devices with the latest updates from the server to ensure top-notch performance and security.<\/p>\n<p>A <a href=\"https:\/\/eluminoustechnologies.com\/hire-developers\/flutter\/\" target=\"_blank\" rel=\"noopener\"><strong>flutter app developer <\/strong><\/a>can build such a mobile app by using reactive programming, which is a way to solve problems by handling multiple data streams asynchronously.<\/p>\n<h3><em>Flutter BLoC Pattern<\/em><\/h3>\n<p>To understand what follows, you need to know <a href=\"https:\/\/eluminoustechnologies.com\/blog\/create-your-first-flutter-app\/\" target=\"_blank\" rel=\"noopener\">how to build a Flutter app<\/a>. We have covered the topic in our blog previously, in addition to a post about <a href=\"https:\/\/eluminoustechnologies.com\/blog\/how-to-create-flutter-widget\/\" target=\"_blank\" rel=\"noopener\">how to create Flutter widgets<\/a>. If you are new to <a href=\"https:\/\/eluminoustechnologies.com\/mobile-app-development\" target=\"_blank\" rel=\"noopener\"><strong>Flutter app development<\/strong><\/a>, reading those two posts will help you understand the subject of this post better.<\/p>\n<p>BLoC (Business Logic) pattern builds upon reactive programming to create reactive Flutter apps. In BLoC, all the business logic side implementations are put in one place that acts as a go-between for network elements and UI screens to carry events\/data back and forth.<\/p>\n<p><img decoding=\"async\" class=\"wp-image-2637 aligncenter lazyload\" data-src=\"https:\/\/b4130876.smushcdn.com\/4130876\/wp-content\/uploads\/2019\/12\/BLoC-1.png?lossy=2&strip=1&webp=1\" alt=\"BLoC-1\" width=\"617\" height=\"463\" title=\"\" data-srcset=\"https:\/\/b4130876.smushcdn.com\/4130876\/wp-content\/uploads\/2019\/12\/BLoC-1.png?lossy=2&amp;strip=1&amp;webp=1 617w, https:\/\/b4130876.smushcdn.com\/4130876\/wp-content\/uploads\/2019\/12\/BLoC-1.png?size=128x96&amp;lossy=2&amp;strip=1&amp;webp=1 128w, https:\/\/b4130876.smushcdn.com\/4130876\/wp-content\/uploads\/2019\/12\/BLoC-1.png?size=256x192&amp;lossy=2&amp;strip=1&amp;webp=1 256w, https:\/\/b4130876.smushcdn.com\/4130876\/wp-content\/uploads\/2019\/12\/BLoC-1.png?size=384x288&amp;lossy=2&amp;strip=1&amp;webp=1 384w, https:\/\/b4130876.smushcdn.com\/4130876\/wp-content\/uploads\/2019\/12\/BLoC-1.png?size=512x384&amp;lossy=2&amp;strip=1&amp;webp=1 512w\" data-sizes=\"auto\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 617px; --smush-placeholder-aspect-ratio: 617\/463;\" data-original-sizes=\"(max-width: 617px) 100vw, 617px\"><\/p>\n<div class=\"blue-bg-box-small text-align-center mb-4\"><em>Source: Stack Secrets<\/em><\/div>\n<p>In other words, the UI part does not handle any logic in BLoC pattern; not even data validations. The aim of doing this is simple \u2013 to create a business logic and data layers that can be shared while focusing on the presentation layer for each mobile platform.<\/p>\n<h3><em>Building a Reactive Flutter App Using BLoC<\/em><\/h3>\n<p>To understand how BLoC helps you build reactive Flutter apps, let\u2019 consider the basic counter app that you get by default when first creating a new project in <a href=\"https:\/\/eluminoustechnologies.com\/hire-developers\/flutter\/\" target=\"_blank\" rel=\"noopener\"><strong>Flutter app development<\/strong><\/a>.<\/p>\n<p><img decoding=\"async\" class=\"wp-image-2638 aligncenter lazyload\" data-src=\"https:\/\/b4130876.smushcdn.com\/4130876\/wp-content\/uploads\/2019\/12\/initial-counter.gif?lossy=2&strip=1&webp=1\" alt=\"initial-counter\" width=\"285\" height=\"508\" title=\"\" data-srcset=\"https:\/\/b4130876.smushcdn.com\/4130876\/wp-content\/uploads\/2019\/12\/initial-counter.gif?lossy=2&amp;strip=1&amp;webp=1 285w, https:\/\/b4130876.smushcdn.com\/4130876\/wp-content\/uploads\/2019\/12\/initial-counter.gif?size=128x228&amp;lossy=2&amp;strip=1&amp;webp=1 128w\" data-sizes=\"auto\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 285px; --smush-placeholder-aspect-ratio: 285\/508;\" data-original-sizes=\"(max-width: 285px) 100vw, 285px\"><\/p>\n<div class=\"blue-bg-box-small text-align-center mb-4\"><em>Source: David Anaya<\/em><\/div>\n<p>In this app, you can see a counter whose value increases every time you press the floating button. To examine the code of this app, you can navigate to the <em>main.dart<\/em> file using your preferred IDE. And this is what you\u2019ll see,<\/p>\n<pre class=\"lang:default decode:true \">import 'package:flutter\/material.dart';\r\n\r\nvoid main() =&gt; runApp(MyApp());\r\n\r\nclass MyApp extends StatelessWidget {\r\n@override\r\nWidget build(BuildContext context) {\r\nreturn MaterialApp(\r\ntitle: 'Flutter Demo',\r\ntheme: ThemeData(\r\nprimarySwatch: Colors.blue,\r\n),\r\nhome: MyHomePage(title: 'Flutter Demo Home Page'),\r\n);\r\n}\r\n}\r\n\r\nclass MyHomePage extends StatefulWidget {\r\nMyHomePage({Key key, this.title}) : super(key: key);\r\nfinal String title;\r\n\r\n@override\r\n_MyHomePageState createState() =&gt; _MyHomePageState();\r\n}\r\n\r\nclass _MyHomePageState extends State&lt;MyHomePage&gt; {\r\n\tint _counter = 0;\r\n\r\n\tvoid _incrementCounter() {\r\n\tsetState(() {\r\n\t_counter++;\r\n});\r\n}\r\n\r\n@override\r\nWidget build(BuildContext context) {\r\nreturn Scaffold(\r\nappBar: AppBar(\r\ntitle: Text(widget.title),\r\n),\r\nbody: Center(\r\nchild: Column(\r\nmainAxisAlignment: MainAxisAlignment.center,\r\nchildren: &lt;Widget&gt;[\r\n\tText(\r\n\t'You have pushed the button this many times:',\r\n\t),\r\n\tText(\r\n\t'$_counter',\r\n\tstyle: Theme.of(context).textTheme.display1,\r\n\t),\r\n\t],\r\n\t),\r\n\t),\r\n\tfloatingActionButton: FloatingActionButton(\r\n\tonPressed: _incrementCounter,\r\n\ttooltip: 'Increment',\r\n\tchild: Icon(Icons.add),\r\n\t),\r\n\t);\r\n}\r\n}<\/pre>\n<h3>Let us examine some key elements of this code.<\/h3>\n<ul>\n<li><em>counter<\/em> is the variable that stores the counter\u2019s value<\/li>\n<li><em>incrementCounter<\/em> is the function that increases the value of _counter<\/li>\n<li><em>floatingButton<\/em> executes the <em>_incrementCounter<\/em> function<\/li>\n<\/ul>\n<p>Here, when the data (<em>_counter<\/em>) changes based on user action (<em>floatingButton<\/em>), the widget has to be rendered again. This can be done by using a <em>StatefulWidget<\/em> along with a <em>setState()<\/em> function.<\/p>\n<p>The code for doing this is pretty straightforward. However, will it still work if you choose to share the <em>_counter<\/em> variable\u2019s value on a different page within your app? The answer is it won\u2019t, since the data is bound locally to your widget.<\/p>\n<p>Instead, what you need to do is move the data and its updating mechanisms to another place that is accessible from any page\/widget within your application. This is exactly what BLoC allows you to do.<\/p>\n<h3><em>Using BLoC for Counter App<\/em><\/h3>\n<p>The first step is to create a new class that acts as the source of truth for your counter. This class will store the counter\u2019s value as a private variable and use Streams and Sinks to interact with it.<\/p>\n<p>While both are provided by a <em>StreamController<\/em>, <em>Sinks<\/em> are used to update the events\/data while <em>Streams<\/em> are used to listen to the changes.<\/p>\n<pre class=\"lang:default decode:true \">import 'dart:async';\r\n\r\nimport 'package:rxdart\/rxdart.dart';\r\nimport 'package:rxdart\/subjects.dart';\r\n\r\nclass CounterBloc {\r\nint _counter = 0;\r\n\r\nfinal _counter$ = BehaviorSubject&lt;int&gt;(seedValue: 0);\r\nfinal _incrementController = StreamController&lt;void&gt;();\r\n\r\nCounterBloc() {\r\n_incrementController.stream.listen((void _) =&gt; _counter$.add(++_counter));\r\n}\r\n\r\nSink&lt;void&gt; get increment =&gt; _incrementController.sink;\r\n\r\nStream&lt;int&gt; get counter$ =&gt; _counter$.stream;\r\n\r\nvoid dispose() {\r\n_incrementController.close();\r\n_counter$.close();\r\n}\r\n}<\/pre>\n<p>In this case, we use <em>counter$<\/em> to depict the changes to <em>_counter<\/em> and <em>increment<\/em> for increasing its value.<\/p>\n<p>Look closer at the constructor and you\u2019ll see how the input sink is linked to the output stream. This ensures that a new counter value is emitted after the execution of every increment.<\/p>\n<p>Now that you\u2019ve coded the logic, you need a way to access it through a widget. For this, you can use <em>InheritedWidget,<\/em> which is a special kind of widget that lets you broadcast information throughout the widget tree. In <a href=\"https:\/\/eluminoustechnologies.com\/hire-developers\/flutter\/\" target=\"_blank\" rel=\"noopener\"><strong>Flutter app development<\/strong><\/a>, <em>InheritedWidget<\/em> ensures that if there are any changes, all widgets using it will be re-rendered as well.<\/p>\n<pre class=\"lang:default decode:true \">import 'package:flutter\/material.dart';\r\n\r\nimport 'package:flutter_counter_bloc\/bloc\/counter_bloc.dart';\r\n\r\nclass BlocProvider extends InheritedWidget {\r\nfinal CounterBloc bloc;\r\n\r\nBlocProvider({Key key, this.bloc, child}) : super(key: key, child: child);\r\n\r\n@override\r\nbool updateShouldNotify(InheritedWidget oldWidget) =&gt; true;\r\n\r\nstatic CounterBloc of(BuildContext context) =&gt;\r\n(context.inheritFromWidgetOfExactType(BlocProvider) as BlocProvider).bloc;<\/pre>\n<p>&nbsp;<\/p>\n<p>With this, you have completed the most essential part of using BLoC to build a reactive mobile app in Flutter. Now comes the task of simplifying the main widget. Note \u2013 since your app\u2019s state is now in the BLoC, you don\u2019t require a <em>StatefulWidget<\/em>. Instead, you can use the state via the <em>BlocProvider<\/em>.<\/p>\n<pre class=\"lang:default decode:true \">import 'package:flutter\/material.dart';\r\nimport 'package:flutter_counter_bloc\/bloc\/bloc_provider.dart';\r\nimport 'package:flutter_counter_bloc\/bloc\/counter_bloc.dart';\r\n\r\nvoid main() {\r\nfinal bloc = CounterBloc();\r\nrunApp(MyApp(bloc));\r\n}\r\n\r\nclass MyApp extends StatelessWidget {\r\nfinal CounterBloc bloc;\r\n\r\nMyApp(this.bloc);\r\n\r\n@override\r\nWidget build(BuildContext context) {\r\nreturn BlocProvider(\r\nbloc: bloc,\r\nchild: MaterialApp(\r\ntitle: 'Flutter Demo',\r\ntheme: ThemeData(\r\nprimarySwatch: Colors.blue,\r\n),\r\nhome: MyHomePage(title: 'Flutter Demo Home Page'),\r\n));\r\n}\r\n}\r\n\r\nclass MyHomePage extends StatelessWidget {\r\nMyHomePage({Key key, this.title}) : super(key: key);\r\nfinal String title;\r\n\r\n@override\r\nWidget build(BuildContext context) {\r\nfinal bloc = BlocProvider.of(context);\r\nreturn Scaffold(\r\nappBar: AppBar(\r\ntitle: Text(title),\r\n),\r\nbody: Center(\r\nchild: Column(\r\nmainAxisAlignment: MainAxisAlignment.center,\r\nchildren: &lt;Widget&gt;[\r\nStreamBuilder(\r\nstream: bloc.counter$,\r\nbuilder: (context, snapshot) =&gt; snapshot.hasData\r\n? Text('${snapshot.data}',\r\nstyle: Theme.of(context).textTheme.display1)\r\n: CircularProgressIndicator()),\r\n],\r\n),\r\n),\r\nfloatingActionButton: FloatingActionButton(\r\nonPressed: () =&gt; bloc.increment.add(null),\r\ntooltip: 'Increment',\r\nchild: Icon(Icons.add),\r\n),\r\n);\r\n}\r\n}<\/pre>\n<p>In BLoC <a href=\"https:\/\/eluminoustechnologies.com\/hire-developers\/flutter\/\" target=\"_blank\" rel=\"noopener\"><strong>Flutter app development<\/strong><\/a>, the <em>BlocProvider<\/em> encompasses the whole application, which means it resides at the top of your widget tree and can be accessed by any widget.<\/p>\n<p>The <em>increment sink<\/em> is used to create a new event while the <em>counter$<\/em> stream, along with a <em>StreamBuilder<\/em>, is used to re-render the counter after the emission of every new value.<\/p>\n<h3><em>Summing It Up<\/em><\/h3>\n<p>While this design might seem complex, it comes into its own when you add more widgets and state and share this state in several widgets. In true reactive programming fashion, there is now a single source of logic that stands separate from the app\u2019s presentation\/UI layer. And the moment the counter\u2019s value is changed, everyone is notified.<\/p>\n<p>Having said that, this is the most basic form of BLoC you can implement in Flutter. However, the overall concept remains the same irrespective of your use case. With the help of BLoC, your <a href=\"https:\/\/eluminoustechnologies.com\/hire-developers\/flutter\/\" target=\"_blank\" rel=\"noopener\"><strong>Flutter app developer<\/strong><\/a> can ensure your app\u2019s state management is handled efficiently, which is an invaluable attribute to have as your app grows in terms of features, user base, and complexity.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Flutter, since its debut in May 2017, has grown by leaps and bounds as a mobile app development framework. Google has consistently released improved iterations&#8230;<\/p>\n","protected":false},"author":7,"featured_media":2639,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[91],"tags":[235,234,237,273],"class_list":["post-2634","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-mobile-apps","tag-flutter-app-developer","tag-flutter-app-development","tag-mobile-app-development","tag-reactive-app-with-flutter"],"acf":[],"_links":{"self":[{"href":"https:\/\/eluminoustechnologies.com\/blog\/wp-json\/wp\/v2\/posts\/2634","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/eluminoustechnologies.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/eluminoustechnologies.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/eluminoustechnologies.com\/blog\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/eluminoustechnologies.com\/blog\/wp-json\/wp\/v2\/comments?post=2634"}],"version-history":[{"count":2,"href":"https:\/\/eluminoustechnologies.com\/blog\/wp-json\/wp\/v2\/posts\/2634\/revisions"}],"predecessor-version":[{"id":24602,"href":"https:\/\/eluminoustechnologies.com\/blog\/wp-json\/wp\/v2\/posts\/2634\/revisions\/24602"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/eluminoustechnologies.com\/blog\/wp-json\/wp\/v2\/media\/2639"}],"wp:attachment":[{"href":"https:\/\/eluminoustechnologies.com\/blog\/wp-json\/wp\/v2\/media?parent=2634"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/eluminoustechnologies.com\/blog\/wp-json\/wp\/v2\/categories?post=2634"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/eluminoustechnologies.com\/blog\/wp-json\/wp\/v2\/tags?post=2634"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}