<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Greg Perry</title>
    <description>The latest articles on DEV Community by Greg Perry (@gtfperry).</description>
    <link>https://dev.to/gtfperry</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3422163%2F272eb819-a50d-4f53-91ae-2004865b5e22.jpeg</url>
      <title>DEV Community: Greg Perry</title>
      <link>https://dev.to/gtfperry</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gtfperry"/>
    <language>en</language>
    <item>
      <title>StateX By Example</title>
      <dc:creator>Greg Perry</dc:creator>
      <pubDate>Sat, 09 Aug 2025 03:02:24 +0000</pubDate>
      <link>https://dev.to/gtfperry/statex-by-example-28cb</link>
      <guid>https://dev.to/gtfperry/statex-by-example-28cb</guid>
      <description>&lt;p&gt;&lt;em&gt;Learn StateX using its example app.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;StateX is a class found in the &lt;a href="https://pub.dev/packages/state_extended" rel="noopener noreferrer"&gt;state_extended&lt;/a&gt; package. It merely ‘extends’ the capabilities of Flutter’s State class with the addition of a Controller class, a built-in FutureBuilder, and a built-in InheritedWidget. This package was recently accepted by &lt;a href="https://fluttergems.dev/packages/state_extended/" rel="noopener noreferrer"&gt;Flutter Gems&lt;/a&gt; under the category, &lt;a href="https://fluttergems.dev/flutter-framework/" rel="noopener noreferrer"&gt;Flutter Framework&lt;/a&gt;. In this article, a review of what it can do for you will involve a walk through its accompanying &lt;a href="https://github.com/AndriousSolutions/state_extended/tree/master/example" rel="noopener noreferrer"&gt;example app&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Index of Topics
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;From The Start&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;First Class&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;A State of Control&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Build Better&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;The Three Count&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;A Separate State&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Inherited Performance&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Build Once And Forget It&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Less Is More&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Note The Change&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;It’s a Do-over&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;A New State&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Keep Control&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Keep Count&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Make A New Start&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Learn by Example&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;A Singular Approach&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;It’s All Timing&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Adaptive Abstraction&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Unknown Potential&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;The Many Constructs&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Handle Your Errors&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;A Better View&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Trouble From The Start&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;To Catch An Error&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;To Err Is Programming&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;To Build Or Not To Build&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Quick Reference&lt;/em&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;StateX Class&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;StateXController Class&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Initialization Handlers&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Event Handling&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Error Handler&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Presented in this article will be a series of screenshots conveying the example app’s source code. Each screenshot will be accompanied by one or more paragraphs explaining the function and features on display. Further, the screenshots’ captions will be linked to the very source code in its &lt;a href="https://github.com/AndriousSolutions/state_extended" rel="noopener noreferrer"&gt;Github repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let’s begin.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh3wd4qq3ex5mg71che99.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh3wd4qq3ex5mg71che99.png" width="800" height="392"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://andrious.medium.com/my-medium-9de112c2d85c" rel="noopener noreferrer"&gt;Other Stories by Greg Perry&lt;/a&gt;



&lt;h3&gt;
  
  
  From The Start &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The first set of screenshots below starts with the &lt;strong&gt;main&lt;/strong&gt; () function. Not a hard-and-fast rule, but you’ll notice I use ‘export files’ to keep the number of import statements used to a more manageable nmber. Instead of reams of &lt;strong&gt;import&lt;/strong&gt; statements at the start of every Dart file, I followed the Dart team’s approach to &lt;a href="https://www.dartlang.org/guides/libraries/create-library-packages#organizing-a-library-package" rel="noopener noreferrer"&gt;organizing a library package&lt;/a&gt;. You can see the next two screenshots export the very files highlighted with red arrows in the first screenshot below. As a result, there’s only one import statement required for the &lt;strong&gt;main&lt;/strong&gt; () function (Tap the screenshots for a closer look).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F96swzfkiucs3df11w81m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F96swzfkiucs3df11w81m.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/main.dart" rel="noopener noreferrer"&gt;main.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjgs4gcd8c1cfwpf7a5i3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjgs4gcd8c1cfwpf7a5i3.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/src/view.dart" rel="noopener noreferrer"&gt;view.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftrr0fnoad0rtaz7z55fk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftrr0fnoad0rtaz7z55fk.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/src/controller.dart" rel="noopener noreferrer"&gt;controller.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  First Class &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;You can see it’s the &lt;em&gt;MyApp&lt;/em&gt; widget that’s called in the &lt;strong&gt;runApp&lt;/strong&gt;() function. That class is presented in the first screenshot below — and note only three import statements. Further down the library file, you’re introduced to the State class, &lt;em&gt;_MyAppState&lt;/em&gt; (second screenshot below). Here, we encounter the first class from the &lt;a href="https://pub.dev/packages/state_extended" rel="noopener noreferrer"&gt;state_extended&lt;/a&gt; package, &lt;em&gt;AppStateX&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2jygg5pxafa2bio9ykr2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2jygg5pxafa2bio9ykr2.png" width="800" height="696"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/view/my_app.dart" rel="noopener noreferrer"&gt;my_app.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc17pzxu0gzbdg3wpf4fi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc17pzxu0gzbdg3wpf4fi.png" width="800" height="707"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/view/my_app.dart#L29" rel="noopener noreferrer"&gt;my_app.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbwqphactlcfcy8dx9zhk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbwqphactlcfcy8dx9zhk.png" width="800" height="696"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/lib/part04_app_statex.dart#L14" rel="noopener noreferrer"&gt;part04_app_statex.dart.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  A State of Control &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;In the second screenshot above, you can see how SOC’s are assigned to a State object. Generally, the State object worries about the interface, while those ‘State Object Controllers’ worry about everything else. In the last screenshot above, you can see that the AppStateX class even worries about Error Handling as well as activates its built-in InheritedWidget (more on that later). The AppStateX class is an extension of another class from the state_extended package called &lt;em&gt;StateX&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Build Better &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Of course, the AppStateX class has a &lt;strong&gt;build&lt;/strong&gt;() function, but you’re discouraged from using that function in your apps — not directly anyway. However, in this example app, I’ll use it to assign boolean values to Flutter’s development tools. The first screenshot below shows you how that’s done. The video demonstrates those tools. Further note in the first screenshot, the &lt;strong&gt;return&lt;/strong&gt; statement calls AppStateX’s own &lt;strong&gt;build&lt;/strong&gt;() function. In turn, that eventually calls the &lt;strong&gt;builder&lt;/strong&gt;() function (second screenshot) where additional ‘development tool’ values are taken in by the MaterialApp widget.&lt;/p&gt;

&lt;p&gt;You see, you’re to ignore the &lt;strong&gt;build&lt;/strong&gt;() function in a StateX object class. You would use the &lt;strong&gt;builder&lt;/strong&gt;() function instead to take full advantage of StateX’s functions and features. If you do use the &lt;strong&gt;build&lt;/strong&gt;() function, it’s then just like another State class.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F624%2F1%2A8sVqTDg2ARZPI_GZdqGGzA.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F624%2F1%2A8sVqTDg2ARZPI_GZdqGGzA.gif" width="1024" height="1024"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu9a3xbfi7oz9ry2cwvv6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu9a3xbfi7oz9ry2cwvv6.png" width="800" height="692"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/view/my_app.dart#L71" rel="noopener noreferrer"&gt;my_app&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl1mvwtz5a88f07q117b9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl1mvwtz5a88f07q117b9.png" width="800" height="698"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/view/my_app.dart#L106" rel="noopener noreferrer"&gt;my_app&lt;/a&gt;



&lt;h3&gt;
  
  
  The Three Count &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The Page1 widget is presented to the user when the app starts up. The second screenshot below conveys the Controller objects instantiated for its State object, &lt;em&gt;Page1State&lt;/em&gt;. It’s the third screenshot that displays not one but three counters——each conceived in a different way.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm0cecalpk5v6v93buvz1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm0cecalpk5v6v93buvz1.png" width="800" height="685"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/view/my_app.dart#L114" rel="noopener noreferrer"&gt;my_app.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2xdvjnzlkcfwnkv9a06j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2xdvjnzlkcfwnkv9a06j.png" width="800" height="697"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/view/page_01.dart#L19" rel="noopener noreferrer"&gt;page_01.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg4nl67d5cafe2e5f76l2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg4nl67d5cafe2e5f76l2.png" width="800" height="642"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  A Separate State &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;In the video below, the counter is incremented three times. Note, the &lt;strong&gt;Text&lt;/strong&gt; widget and the &lt;strong&gt;setBuilder&lt;/strong&gt;() function will increment, but the third counter residing in a separate StatefulWidget does not. Perfectly normal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiec03mhlhrvmz47pfgun.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiec03mhlhrvmz47pfgun.gif" width="600" height="1215"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcj1vat91dgalh8t208ln.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcj1vat91dgalh8t208ln.png" width="800" height="715"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/view/page_01.dart#L164" rel="noopener noreferrer"&gt;page_01.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwv5zsn7u5ej2pesqbtj3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwv5zsn7u5ej2pesqbtj3.png" width="800" height="688"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/lib/part06_inherited_widget_state_mixin.dart#L22" rel="noopener noreferrer"&gt;part06_inherited_widget_state_mixin.dart&lt;/a&gt;



&lt;p&gt;As you know, in Flutter, a State object’s &lt;strong&gt;setState&lt;/strong&gt;() function will have its &lt;strong&gt;build&lt;/strong&gt;() function called again in the next frame cycle. The video above demonstrates this. The first screenshot above is the example app’s code in the &lt;strong&gt;builder&lt;/strong&gt;() function that’s run again and again with every press of the button. The second screenshot above is the inner workings of the StateX object. You can see it’s there where the &lt;strong&gt;builder&lt;/strong&gt;() function is called. Since the &lt;em&gt;_useInherited&lt;/em&gt; variable is set to false, the &lt;strong&gt;builder&lt;/strong&gt;() function is called every time. However, if the variable is set to true, the &lt;strong&gt;builder&lt;/strong&gt;() function is not called ever again! Let’s see how that works below.&lt;/p&gt;

&lt;h3&gt;
  
  
  Inherited Performance &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;In the video below, things have changed. When you ‘turn on’ the built-in InheritedWidget (I’ll explain how that’s done shortly), the &lt;em&gt;_useInherited&lt;/em&gt; variable is set to true in the StateX object. The first screenshot below highlights what that means.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff64ldp2av5iu9hcyuupp.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff64ldp2av5iu9hcyuupp.gif" width="600" height="1215"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi5h89chonjysdqeaw6tu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi5h89chonjysdqeaw6tu.png" width="800" height="688"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/lib/part06_inherited_widget_state_mixin.dart#L22" rel="noopener noreferrer"&gt;part06_inherited_widget_state_mixin.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyc0xp7ihem6n3hkw7zof.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyc0xp7ihem6n3hkw7zof.png" width="800" height="696"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/view/page_01.dart#L183" rel="noopener noreferrer"&gt;page_01.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  Build Once And Forget It &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;builder&lt;/strong&gt;() function is only called once and is then wrapped in the built-in InheritedWidget. That means that &lt;strong&gt;Text&lt;/strong&gt; widget will never be called and rebuilt again — it doesn’t increment with every push of the button anymore. You see, the whole screen is no longer rebuilt again and again. Do you follow? However, the other two counters do increment. That’s because they are both dependencies of the StateX object’s built-in InheritedWidget. Only those widgets are rebuilt in the interface making for better performance. This is nothing new in Flutter.&lt;/p&gt;

&lt;p&gt;In the second screenshot below, we see the &lt;strong&gt;setBuilder&lt;/strong&gt;() function is very much like the &lt;a href="https://api.flutter.dev/flutter/widgets/Builder-class.html" rel="noopener noreferrer"&gt;Builder&lt;/a&gt; widget supplies a BuildContext parameter and returns a widget. This function is from the Mixin found in the state_extended package called &lt;em&gt;InheritedWidgetStateMixin&lt;/em&gt;. We’ve been looking at its inner workings for some time now with its &lt;strong&gt;buildF&lt;/strong&gt;() function (first screenshot below), but now we’ll examine its &lt;strong&gt;setBuilder&lt;/strong&gt;() function.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F03002boceosoqwll2h1x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F03002boceosoqwll2h1x.png" width="800" height="688"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/lib/part06_inherited_widget_state_mixin.dart#L22" rel="noopener noreferrer"&gt;part06_inherited_widget_state_mixin.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmlp0exteg6lzg5pcnozi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmlp0exteg6lzg5pcnozi.png" width="800" height="696"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/lib/part04_app_statex.dart#L386" rel="noopener noreferrer"&gt;part04_app_statex.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fki5vs9gvwdhnajd3j169.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fki5vs9gvwdhnajd3j169.png" width="800" height="696"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/lib/part04_app_statex.dart#L727" rel="noopener noreferrer"&gt;part04_app_statex.dart&lt;/a&gt;



&lt;p&gt;In the second screenshot above, we’re presented with the &lt;strong&gt;setBuilder&lt;/strong&gt;() function. Now you see why the counter is incremented whether the &lt;strong&gt;useInherited&lt;/strong&gt; getter returns true or false — the &lt;strong&gt;builder&lt;/strong&gt;() function is called in either case. Looking at the third screenshot, if set to true, the &lt;strong&gt;builder&lt;/strong&gt;() function is wrapped in the StatelessWidget, &lt;em&gt;StateDependentWidget&lt;/em&gt;. It is that widget that becomes a ‘dependent’ of the built-in InheritedWidget using the line:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;stateMixin?.dependOnInheritedWidget(context)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I’d say the most powerful feature of Flutter’s InheritedWidget is that whenever it’s called again, its dependency widgets will be rebuilt (their &lt;strong&gt;build&lt;/strong&gt;() functions called again). Nothing new here. It’s all Flutter.&lt;/p&gt;

&lt;p&gt;The third and final counter is also incremented. As you see in the first screenshot below, it’s the one encased in a StatefulWidget. Its State object is made an dependent on Page1State’s built-in InheritedWidget as well. In the third screenshot, it’s the Controller object’s &lt;strong&gt;buildThisState&lt;/strong&gt;() function that assigns this dependency.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff64ldp2av5iu9hcyuupp.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff64ldp2av5iu9hcyuupp.gif" width="600" height="1215"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr7y63kpmkm3366lhqgfs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr7y63kpmkm3366lhqgfs.png" width="800" height="703"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/view/page_01.dart#L194" rel="noopener noreferrer"&gt;page_01.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8b14u4zwdkhcxps4kma8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8b14u4zwdkhcxps4kma8.png" width="800" height="699"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/view/page_01.dart#L357" rel="noopener noreferrer"&gt;page_01.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  Less Is More &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Let’s look at another example. Viewing the video below, know it is only the red ‘word pairs’ being rebuilt in set intervals — it’s the only portion of the screen changing every few seconds. That is the only portion of the screen being repainted. The rest of the screen is left untouched. The less the Widget tree is rebuilt, the better the overall performance. In the screenshot below, you see it's the getter, &lt;em&gt;wordPair&lt;/em&gt;, that supplies these word-pairs. I’ll show how this works next.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnuwwciimv0li2nvduebs.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnuwwciimv0li2nvduebs.gif" width="624" height="1264"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftmse6fzsnqt0h2jxu7ep.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftmse6fzsnqt0h2jxu7ep.png" width="430" height="910"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh9qi446r4pw2a8en67kk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh9qi446r4pw2a8en67kk.png" width="800" height="703"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/view/page_01.dart#L164" rel="noopener noreferrer"&gt;page_01.dart&lt;/a&gt;



&lt;p&gt;In the first screenshot below, the getter uses the &lt;strong&gt;SetBuilder&lt;/strong&gt; widget. This widget is also from the &lt;a href="https://pub.dev/packages/state_extended" rel="noopener noreferrer"&gt;state_extended&lt;/a&gt; package. It involves the App State object’s &lt;em&gt;dataObj&lt;/em&gt; property. It’s of type &lt;em&gt;object&lt;/em&gt;, and so you can pass ‘anything’ down the Widget tree. In the case of this example app, it’s a String object that is passed down. See the second screenshot below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwxhzgmc9e2kzibgcvi8c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwxhzgmc9e2kzibgcvi8c.png" width="800" height="701"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/controller/word_pair_timer.dart#L162" rel="noopener noreferrer"&gt;word_pair_timer.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftf9v3ubcu1rp4e1zh66g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftf9v3ubcu1rp4e1zh66g.png" width="800" height="700"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/view/my_app.dart#L30" rel="noopener noreferrer"&gt;my_app.dart&lt;/a&gt;



&lt;p&gt;The &lt;strong&gt;SetBuilder&lt;/strong&gt; widget rebuilds when that String object changes in value. In the first screenshot below, that occurs when a new word-pair is assigned. Finally, the setter, &lt;em&gt;dataObject&lt;/em&gt;, calls the AppStateX’s InheritedWidget with the &lt;strong&gt;notifyClients&lt;/strong&gt; () function. Doing so, will rebuild any and all &lt;strong&gt;SetBuilder&lt;/strong&gt; widgets — in fact, any widget set as a dependency to the AppStateX’s InheritedWidget. Makes for an efficient interface.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdd8xwii2pnzouz3mdl3p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdd8xwii2pnzouz3mdl3p.png" width="800" height="702"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/controller/word_pair_timer.dart#L185" rel="noopener noreferrer"&gt;word_pair_timer.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbs39va5rpjj1uvkly26l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbs39va5rpjj1uvkly26l.png" width="800" height="692"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/lib/part17_app_state_mixin.dart#L22" rel="noopener noreferrer"&gt;part17_app_state_mixin.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  Note The Change &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Finally, the video below demonstrates what happens with the three counters when selecting the Switch, ‘Use built-in ChangNotifier.’ All three counters now increment. It’s easy enough to understand the first two. We’ve returned to rebuilding the whole interface again. Both the &lt;strong&gt;Text&lt;/strong&gt; widget and &lt;strong&gt;setBuilder&lt;/strong&gt;() function will rebuild, but why would the third counter in its separate StatefulWidget? It shouldn’t increment — it’s no longer dependent on an InheritedWidget?! That’s because it’s become a &lt;em&gt;Listener&lt;/em&gt;. State Object Controllers have a built-in &lt;a href="https://api.flutter.dev/flutter/foundation/ChangeNotifier-class.html" rel="noopener noreferrer"&gt;&lt;em&gt;ChangeNotifier&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnb8sc8ui4on97ss7fu6o.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnb8sc8ui4on97ss7fu6o.gif" width="624" height="1264"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe17n72pp3k5p0slxos4p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe17n72pp3k5p0slxos4p.png" width="800" height="703"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/controller/controller.dart#L151" rel="noopener noreferrer"&gt;controller.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpaatxt8mg9jfk0qjj6h3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpaatxt8mg9jfk0qjj6h3.png" width="800" height="698"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/lib/part12_rebuild_controller_states_mixin.dart#L53" rel="noopener noreferrer"&gt;part12_rebuild_controller_states_mixin.dart&lt;/a&gt;



&lt;p&gt;In the first screenshot above, you can see the Controller’s &lt;strong&gt;buildThisState&lt;/strong&gt;() function will also include Page1’s State object as a ‘State Listener’ if the variable, &lt;em&gt;useChangeNotifier&lt;/em&gt;, is set to true. That’s exactly what happens in the video above.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;rebuild = addStateListener(state);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In the second screenshot above, you can see the State object’s &lt;strong&gt;setState&lt;/strong&gt;() function is called when that Listener is notified. They’re notified through the Controller which had added them. This is done in the Controller’s version of the &lt;strong&gt;setState&lt;/strong&gt;() function. Note, in the first screenshot below, its &lt;strong&gt;setState&lt;/strong&gt;() function also includes notifying any Listeners:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;notifyListeners();&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The next two screenshots trace back to Flutter’s own &lt;a href="https://api.flutter.dev/flutter/foundation/ChangeNotifier-class.html" rel="noopener noreferrer"&gt;&lt;em&gt;ChangeNotifier&lt;/em&gt;&lt;/a&gt;class calling its &lt;strong&gt;notifyListeners&lt;/strong&gt;() function and ‘rebuilding’ any and all State objects assigned. See how that works? Just another way of accessing and rebuilding dispersed and remote State objects — via a State Object Controller.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn4mxlap63o3clbkxa44l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn4mxlap63o3clbkxa44l.png" width="800" height="701"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/lib/part02_statex_controller.dart#L145" rel="noopener noreferrer"&gt;part02_statex_controller.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl0ggf9ps5e5pwj0pfviz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl0ggf9ps5e5pwj0pfviz.png" width="800" height="707"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/lib/part12_rebuild_controller_states_mixin.dart#L102" rel="noopener noreferrer"&gt;part12_rebuild_controller_states_mixin.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo1jzg6gewu4a2zpr8vcw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo1jzg6gewu4a2zpr8vcw.png" width="800" height="701"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/lib/part12_rebuild_controller_states_mixin.dart#L148" rel="noopener noreferrer"&gt;part12_rebuild_controller_states_mixin.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  It’s a Do-over &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;To activate its built-in InheritedWidget, a StateX object must be instantiated with the formal parameter, &lt;em&gt;useInherited&lt;/em&gt;, set to true. Notice in the video below, there’s a distinct ‘refresh’ of the screen when the Switch, &lt;em&gt;Use built-in InheritedWidget&lt;/em&gt;, is tapped on. That’s because the App’s whole interface is rebuilt again. Note, it’s also rebuilt again with every change of those Development tools settings introduced earlier. The App’s interface is rebuilt when demonstrating much of this example app’s functionality. That means the &lt;em&gt;MaterialApp&lt;/em&gt; widget in this example app is being called again and again (see the second screenshot below). Let’s how that’s done.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff64ldp2av5iu9hcyuupp.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff64ldp2av5iu9hcyuupp.gif" width="600" height="1215"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkufir23rhhnbrbr0t9zs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkufir23rhhnbrbr0t9zs.png" width="800" height="701"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/view/page_01.dart#L18" rel="noopener noreferrer"&gt;page_01.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3yluce5pakuw7r57u7y6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3yluce5pakuw7r57u7y6.png" width="800" height="699"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/view/my_app.dart#L106" rel="noopener noreferrer"&gt;my_app.dart&lt;/a&gt;



&lt;p&gt;In the first screenshot below, selecting the Switch calls the Controller’s method, &lt;strong&gt;onChangedInherited&lt;/strong&gt;(). Two things need to happen to then activate the StateX object’s built-in InheritedWidget: the whole app interface must be rebuilt and that particular StateX object must be recreated.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fge5n4hcpbem0pwdl9hi4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fge5n4hcpbem0pwdl9hi4.png" width="800" height="700"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/view/page_01.dart#L247" rel="noopener noreferrer"&gt;page_01.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fib8nc2rlbba461r080ku.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fib8nc2rlbba461r080ku.png" width="800" height="697"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/controller/controller.dart#L90" rel="noopener noreferrer"&gt;controller.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  A New State &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;In Flutter, State objects are recreated when their Statefulwidget is assigned a ‘new’ Key value. In the second screenshot above, that’s accomplished with the line, page1Key = null;. Again, nothing new here. This is how Flutter works. The second thing to do is simply rebuild the App’s State object:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;appState?.setState((){});&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Every Controller has a reference for the App’s State object. In the first screenshot below, we see the App’s State object’s &lt;strong&gt;builder&lt;/strong&gt;() function called again. Again, changing any Development tool settings introduced earlier requires the line, appState?.setState((){});.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkevc9rgda8naen7a9mhg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkevc9rgda8naen7a9mhg.png" width="800" height="707"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/view/my_app.dart#L106" rel="noopener noreferrer"&gt;my_app.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7psv1lefzh429xxmyry6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7psv1lefzh429xxmyry6.png" width="800" height="699"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/view/page_01.dart#L9" rel="noopener noreferrer"&gt;page_01.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F77a1ql463jckpo1ual39.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F77a1ql463jckpo1ual39.png" width="800" height="695"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/controller/controller.dart#L11" rel="noopener noreferrer"&gt;controller.dart&lt;/a&gt;



&lt;p&gt;In the second screenshot above is the StatefulWidget, &lt;em&gt;Page1&lt;/em&gt;. Note, if not explicitly provided one, its Key value is supplied by the screen’s Controller, Controller().page1Key. Remember, however, it was set to &lt;strong&gt;null&lt;/strong&gt; with a tap of a Switch. This means the Key value stored in the class property, _page1Key, has now changed to a completely new value. In Flutter, this causes the State object to be recreated. Being recreated, the value passed to this new State object is now set to true: &lt;strong&gt;Controller&lt;/strong&gt;().useInherited&lt;/p&gt;

&lt;h3&gt;
  
  
  Keep Control &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;If you haven’t noticed by now, each State Object Controller class in the example app uses a factory constructor to instantiate only one instance of each class. Three of those classes are conveyed in the screenshots below.&lt;/p&gt;

&lt;p&gt;Again, not a hard-and-fast rule, but I’ve found keeping only one instance of the State Object Controllers has proven well-suited for their role: A class object representing the ‘ongoing state’ of the app in a singular instance. An example of this, of course, is the running count that’s displayed. Its ‘interface settings’ is also maintained by a Controller. Further advantages in using this Singleton Pattern will be explained shortly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk4yss2mspgmertfrsg2k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk4yss2mspgmertfrsg2k.png" width="800" height="690"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/controller/controller.dart#L11" rel="noopener noreferrer"&gt;controller.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwgw1l81winf1vkxe0ogk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwgw1l81winf1vkxe0ogk.png" width="800" height="701"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/controller/word_pair_timer.dart#L1" rel="noopener noreferrer"&gt;word_pair_timer.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdj3bddnboowthpxbbgq3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdj3bddnboowthpxbbgq3.png" width="800" height="702"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/controller/example_app_controller.dart#L11" rel="noopener noreferrer"&gt;example_app_controller.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  Keep Count &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Since it’s a complete recreation of the State object and its counter property, count, we will have to save the count before the switch. Of course, the Controller object will take care of all of this. In the first screenshot below, using its &lt;strong&gt;stateInit&lt;/strong&gt;(State state) function, a controller can determine the StateX object it’s currently working with, and in this case, supply the count to the new screen. Otherwise, after the switch, you would just see zeros. Makes sense?&lt;/p&gt;

&lt;h3&gt;
  
  
  Make A New Start &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Note, the video below further demonstrates this ‘rebuilding of the App’ with the line, appState?.setState((){});.In the video, you see the ‘debug banner’ is turned off and then changing the app’s whole theme from &lt;em&gt;Material3&lt;/em&gt; to &lt;em&gt;Material2&lt;/em&gt;. Both required a new call to the App’s MaterialApp widget.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F20ylsl7r2njfxui7yz7g.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F20ylsl7r2njfxui7yz7g.gif" width="80" height="162"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmwwvgedm5tdcgfzv78dn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmwwvgedm5tdcgfzv78dn.png" width="800" height="703"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/controller/controller.dart#L64" rel="noopener noreferrer"&gt;controller.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdl1ytfm02ucu4dx5ry69.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdl1ytfm02ucu4dx5ry69.png" width="800" height="692"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/view/page_01.dart#L43" rel="noopener noreferrer"&gt;page_01.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  Learn by Example &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This is a ‘demonstration’ app as well. And so, as you see in the second screenshot above, the Page1 State object’s &lt;strong&gt;initState&lt;/strong&gt; () function has many examples of how this &lt;a href="https://pub.dev/packages/state_extended" rel="noopener noreferrer"&gt;state_extended&lt;/a&gt; package empowers you to make versatile and adaptive code by giving you more than one way to retrieve a State object that makes up your App from anywhere at anytime.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Singular Approach &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;By the way, another reason for the Singleton Pattern used by instantiating all the State Object Controllers with a factory constructor is to take advantage of the versability and readability that’s achieved. You can then make any number of construction calls necessary to perform specific tasks throughout the app. An example of this is next.&lt;/p&gt;

&lt;h3&gt;
  
  
  It’s All Timing &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;As you many know, it was the WordPairsTimer controller that was providing those red ‘word pairs’ at set intervals using its getter, &lt;em&gt;wordPair&lt;/em&gt;. In the first screenshot below, you see this controller follows the Singleton pattern. In the second screenshot below, it’s instantiated as one of the controllers to work with the first screen, &lt;em&gt;Page1State&lt;/em&gt;, displaying the word-pairs.&lt;/p&gt;

&lt;p&gt;However, this App has a &lt;a href="https://api.flutter.dev/flutter/material/Drawer-class.html" rel="noopener noreferrer"&gt;Drawer&lt;/a&gt; widget, and whenever it opens, I want to turn off the Timer that’s changing the word-pairs every 5 seconds. The ‘easiest’ means to do this is presented in the third screenshot below — just call the constructor again. The Singleton pattern approach makes this possible.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwgw1l81winf1vkxe0ogk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwgw1l81winf1vkxe0ogk.png" width="800" height="701"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/controller/word_pair_timer.dart#L1" rel="noopener noreferrer"&gt;word_pair_timer.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcn21qknqyv5gju38badb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcn21qknqyv5gju38badb.png" width="800" height="696"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/view/page_01.dart#L18" rel="noopener noreferrer"&gt;page_01.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3glbus51w8r3ppypxaqw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3glbus51w8r3ppypxaqw.png" width="800" height="698"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/view/my_app.dart#L113" rel="noopener noreferrer"&gt;my_app.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  Adaptive Abstraction &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Those construction calls for the WordPairsTimer controller right there in the first page was more for the benefit of the reader. In truth, I would normally only reference the State object’s controller, &lt;em&gt;con&lt;/em&gt;, throughout that interface. This would then incorporate a layer of abstraction to the app. You can see an example of this in the first screenshot below. The interface has no business knowing there’s a word-pair timer running somewhere, and is turned off just before the Drawer is opened. See what I changed I made in the first screenshot below to achieve this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fboi3ukot71s2mdedam03.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fboi3ukot71s2mdedam03.png" width="800" height="693"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/view/my_app.dart#L113" rel="noopener noreferrer"&gt;my_app.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1al2e3lc1i7kjgzjlb6e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1al2e3lc1i7kjgzjlb6e.png" width="800" height="689"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/controller/example_app_controller.dart#L162" rel="noopener noreferrer"&gt;example_app_controller.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F025lknheij3hlf2qmb8n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F025lknheij3hlf2qmb8n.png" width="800" height="695"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/controller/controller.dart#L158" rel="noopener noreferrer"&gt;controller.dart&lt;/a&gt;



&lt;p&gt;The second screenshot above is of the App’s State object controller, &lt;em&gt;ExampleAppController&lt;/em&gt;. You see the new &lt;strong&gt;onOpenDrawer&lt;/strong&gt;() and &lt;strong&gt;onCloseDrawer&lt;/strong&gt;() functions. They, in turn, call their counterparts found in the Controller class. Finally, we see those functions, in the third screenshot above, calling the original methods found in the WordPairsTimer controller. See how that works?&lt;/p&gt;

&lt;h3&gt;
  
  
  Unknown Potential &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Back on the interface side, there’s no hint of what’s going on when the Drawer callback functions fire (see first screenshot below). The WordPair Timer process could be modified down the road or removed outright without changing one bit of the interface. It’s the use of these State Object Controllers that provides this layer of abstraction and makes your code that much more adaptive and its maintenance that much easier.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Many Constructs &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The second screenshot below conveys another example of using multiple constructor calls from the same class. We’re back setting the built-in InheritedWidget on or off with the controller property, &lt;em&gt;useInherited&lt;/em&gt;, for the Page 1 screen. Note the readability. Flutter doesn’t allow dynamic instance variables in the class. The &lt;a href="https://dart.dev/language/constructors#use-an-initializer-list" rel="noopener noreferrer"&gt;initializer list&lt;/a&gt; can only initialize instance variables before the constructor body runs. and so this a more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe9fa5g53dvz5a1qe8qv2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe9fa5g53dvz5a1qe8qv2.png" width="800" height="509"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/view/my_app.dart#L122" rel="noopener noreferrer"&gt;my_app.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa4ha97larw5l9vn63ff0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa4ha97larw5l9vn63ff0.png" width="800" height="640"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/view/page_01.dart#L18" rel="noopener noreferrer"&gt;page_01.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  Handle Your Errors &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;You hope for no errors in your app. However, your app will error. You have to prepare for this fact. The StateX package allows you to prepare for this fact whether they're unexpected errors or anticipated errors at times. Maybe there’s a case where intermittent errors are known to occur in your app — a network drop is known to occur, for example. In certain cases, a process is known to fail. This package gives the means to acknowledge such errors and shut down gracefully if not actually overcome the error and continue running.&lt;/p&gt;

&lt;p&gt;As an example, in the video below, the app intentionally throws an anticipated error with every push of the counter button (see screenshot below). This example app logs many of the events that occur while running, and you can see the error is recognized in the second screenshot. An &lt;strong&gt;onError&lt;/strong&gt;() method fires in a series of State objects all the way back to the App’s State object, &lt;em&gt;_MyAppState&lt;/em&gt;. One of those methods actually recovers from this Exception by incrementing the count regardless.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpxtoq60a0hq0570eqnhx.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpxtoq60a0hq0570eqnhx.gif" width="8" height="16"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx48tp5mocuryd1eyajpz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx48tp5mocuryd1eyajpz.png" width="800" height="701"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/view/page_01.dart#L291" rel="noopener noreferrer"&gt;page_01.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy8izlchavtak8wjy5qvf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy8izlchavtak8wjy5qvf.png" width="509" height="1041"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In truth, it is the App’s State object, &lt;em&gt;_MyAppState&lt;/em&gt;, that catches the error. It then begins a series of &lt;strong&gt;onError&lt;/strong&gt;() function calls. It first calls the State object where the error likely originated. When such a State object is found, its Controllers’ &lt;strong&gt;onError&lt;/strong&gt;() methods are called first before calling its &lt;strong&gt;onError&lt;/strong&gt;() method. It is the App’s State object that finally records and logs the error.&lt;/p&gt;

&lt;p&gt;Back to our example, the third screenshot below highlights when an &lt;strong&gt;onError&lt;/strong&gt;() method in one of the Controllers recognizes the error and increments the counter regardless. A very simple example, but you get the idea.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fohc6u807k7cqpj1yb5a2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fohc6u807k7cqpj1yb5a2.png" width="800" height="694"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/lib/part04_app_statex.dart#L14" rel="noopener noreferrer"&gt;part04_app_statex.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft11dh4fguu6qmze4yvmh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft11dh4fguu6qmze4yvmh.png" width="800" height="687"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/lib/part04_app_statex.dart#L433" rel="noopener noreferrer"&gt;part04_app_statex.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffx4djc7yzhklyyk85xu5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffx4djc7yzhklyyk85xu5.png" width="800" height="657"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/controller/controller.dart#L244" rel="noopener noreferrer"&gt;controller.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  A Better View &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This is not a built-in feature of the state_extended package, but a further demonstration of how to seamlessly implement a feature using a State Object Controller. Instead of the ‘Red Screen of Doom’ that comes with errors while developing in Flutter, how about a more useful, more pleasant-looking error screen? The BuildErrorWidget class integrates such a screen by merely introducing it as a controller to the App’s State object. In the video below, the class allows you to control its use and returns to the original error screen when appropriate while developing, while testing, and while running in production.&lt;/p&gt;

&lt;p&gt;The video below demonstrates this with an error explitcity thrown when going to Page 2 in the example app. You’re able to manually ‘trip errors’ in this example app to demonstrate this package’s error handling. In the video, you see the traditional ‘Red Screen of Doom.’ However, when the ‘Custom Error Screen’ is switched on, the BuildErrorWidget class will assign a custom builder to Flutter’s &lt;a href="https://api.flutter.dev/flutter/widgets/ErrorWidget/builder.html" rel="noopener noreferrer"&gt;&lt;strong&gt;ErrorWidget.builder&lt;/strong&gt;&lt;/a&gt; callback. Now, when such an error occurs, a more helpful error screen is displayed when the intended widget fails to build. Very nice.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F624%2F1%2AdQ5pimFp6yQRRrBUkJAhdA.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F624%2F1%2AdQ5pimFp6yQRRrBUkJAhdA.gif" width="624" height="1264"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvqzrjtc5fnn4d2y8mw8b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvqzrjtc5fnn4d2y8mw8b.png" width="800" height="707"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/view/my_app.dart#L29" rel="noopener noreferrer"&gt;my_app.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F50el3pnmivnllw2yuhak.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F50el3pnmivnllw2yuhak.png" width="800" height="696"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/view/common/controller/build_error_widget.dart#L172" rel="noopener noreferrer"&gt;build_error_widget.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  Trouble From The Start &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The video below throws an error right at the start of the app — in the AppStateX’s &lt;strong&gt;initAsync&lt;/strong&gt;() function. It’s usually at startup when things have trouble — more of an effort may be needed to start successfully. In the video, the example app starts up without incident. However, the app is repeatedly restarted with specific settings switched on to show what the package can do for you if and when your app encounters an error right at startup.&lt;/p&gt;

&lt;p&gt;The ‘Error initAsync() at Startup’ switch is first turned on. When the app starts up again, you are greeted by the good ol’ ‘Red Screen of Boom!’ Nothing left for you to do but try the app again. Happily, you’re able to get into the app again because it actually ‘recovers’ this time. A snackbar appears with the message, ‘An error at startup, but was caught.’ Going back to the Settings screen, you’ll notice the ‘Catch Error’ option is set, Yes. However, in the video, it is set back to ‘No’ so to again demonstrate the custom error screen with another restart. Again, you can’t continue as the app has once again failed at startup, and you’re presented with an error screen. That’s ok. That’s because the app will catch the error the next time it starts up. The error is overcome once again. Let’s see how.&lt;/p&gt;

&lt;p&gt;This video emulates, for example, when the network is down at startup or when it fails to access some critical web service at startup. The app can’t continue — unless it can. That’s where the &lt;strong&gt;catchAsyncError&lt;/strong&gt;() function comes in (see the second screenshot below). The &lt;strong&gt;catchAsyncError&lt;/strong&gt;() function below looks out for an error message containing the string, ‘Error in App’s initAsync()!’ It then acts accordingly. If this function returns &lt;em&gt;false&lt;/em&gt;, the error is not successfully caught, it has failed to recover, and so an error screen is presented. Note, when not caught, the property, &lt;em&gt;catchInitAppAsyncError&lt;/em&gt;, is set to true for next time. Otherwise, the app will never start up successfully. Smart thinking.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F624%2F1%2ABEK3wvrboL6ehoTere5xMQ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F624%2F1%2ABEK3wvrboL6ehoTere5xMQ.gif" width="1024" height="1024"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzlb7prp9fs52bouakr46.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzlb7prp9fs52bouakr46.png" width="800" height="694"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/lib/part05_futurebuilder_state_mixin.dart#L23" rel="noopener noreferrer"&gt;part05_futurebuilder_state_mixin.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb8tvakz1xj56wx50lm9k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb8tvakz1xj56wx50lm9k.png" width="800" height="700"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/controller/example_app_controller.dart#L132" rel="noopener noreferrer"&gt;example_app_conroller.dart&lt;/a&gt;



&lt;p&gt;The first screenshot is of &lt;a href="https://pub.dev/packages/state_extended" rel="noopener noreferrer"&gt;state_extended&lt;/a&gt; package itself. It’s a snapshot of the &lt;strong&gt;build&lt;/strong&gt;() function called by the StateX class. Highlighted is the &lt;strong&gt;catchAsyncError&lt;/strong&gt;() function call. Your &lt;strong&gt;initAsync&lt;/strong&gt;() function has thrown an error, but you’re given an opportunity to possibly recover from the error with the &lt;strong&gt;catchAsyncError&lt;/strong&gt;() function.&lt;/p&gt;

&lt;p&gt;Of course, always returning true and freely ignoring errors would not be advisable. Such decisions will very likely only make your App fail further. It’s for those exceptions where a recovery may be possible or, at the very least, an opportunity to clean up resources and prevent any data corruption before bringing the crash to a ‘soft landing’ and have the app fail gracefully.&lt;/p&gt;

&lt;h3&gt;
  
  
  To Catch An Error &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;In the next video below, you have the means to throw an error when attempting to open Page 2 in the example app. Again, the custom error screen is first demonstrated. However, it’s the ‘Catch Error’ option that’s of interest here. When that is switched on, the &lt;strong&gt;catchAyncError&lt;/strong&gt;() function in the second screenshot below will ‘catch’ the error and return true.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F624%2F1%2A4vTdiJk1PR8qdMjmcn-yHg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F624%2F1%2A4vTdiJk1PR8qdMjmcn-yHg.gif" width="1024" height="1024"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fevwc2ullwoijv3t7hl0y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fevwc2ullwoijv3t7hl0y.png" width="800" height="707"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/controller/another_controller.dart#L61" rel="noopener noreferrer"&gt;another_controller.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftvq36l14dd1wcfxg4ogn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftvq36l14dd1wcfxg4ogn.png" width="800" height="701"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/controller/another_controller.dart#L89" rel="noopener noreferrer"&gt;another_controller.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  To Err Is Programming &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This example app has &lt;em&gt;throw&lt;/em&gt; statements throughout its code. Again, this is to demonstrate this package’s ability to effectively handle errors. Another example is when the ‘Error in Builder’ is switched on. The first screenshot below shows an Exception being thrown. This simulates a Widget failing to be created in a &lt;strong&gt;build&lt;/strong&gt;() function.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F624%2F1%2ArC-1EQb-nd_lm5NzliYnIg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F624%2F1%2ArC-1EQb-nd_lm5NzliYnIg.gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F72mxulai5nwyp8tys0ue.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F72mxulai5nwyp8tys0ue.png" width="800" height="702"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/view/page_02.dart#L123" rel="noopener noreferrer"&gt;page_02.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1csn3rjmy4ehnve8q9po.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1csn3rjmy4ehnve8q9po.png" width="800" height="693"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/app/view/common/controller/build_error_widget.dart#L236" rel="noopener noreferrer"&gt;build_error_widget.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  To Build Or Not To Build &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;As you know now, any Asynchronous operations that may fail in the &lt;strong&gt;initAsync&lt;/strong&gt;() function may be caught by the &lt;strong&gt;catchAsyncError&lt;/strong&gt;() function. However, an error in a &lt;strong&gt;build&lt;/strong&gt;() function can not be explicitly caught. No, if your &lt;strong&gt;build&lt;/strong&gt;() function fails, it’s an error that should *not* happen in production. It’s an error, it will be recorded and logged, but it is not recoverable. Of course, it’s your app, you can address such errors right in your &lt;strong&gt;build&lt;/strong&gt;() function and maybe even recover from it yourself — there’s just no ready means in the StateX class.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quick Reference  &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  StateX Class &lt;a&gt;&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;.appStateX → Retrieves the App's appStateX object. Returns null if not available.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/appStateX.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;.controller → Retrieves the State object's 'current' Controller.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/controller.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;.deactivated → True if deactivated() was called.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/deactivated.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;.disposed → True if disposed() was called.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/disposed.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;.firstBuild → True if build() not called or called once.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/disposed.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;.hiddenAppLifecycle → True if State object was in a 'hidden' state.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/hiddenAppLifecycle.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;.identifier → Unique Srtring identifier foe this StsteX object.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/identifier.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;.inactiveAppLifecycle → True if the State object was in an inactive state.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/inactiveAppLifecycle.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;.isLastState → True if it's the 'latest' StateX object created in the app.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/isLastState.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;.lastSystemEvent → Records the last system event called.StateX  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;didChangeAccessibilityFeatures
&lt;/li&gt;
&lt;li&gt;didChangeLocales
&lt;/li&gt;
&lt;li&gt;didChangeMetrics
&lt;/li&gt;
&lt;li&gt;didChangePlatformBrrightness
&lt;/li&gt;
&lt;li&gt;didChangeTextScalFactor
&lt;/li&gt;
&lt;li&gt;didHaveMemoryPressuure
&lt;/li&gt;
&lt;li&gt;didRequestAppExit&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;.pausedAppLifecycle&lt;/strong&gt; → True if State object was in a paused state.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/pausedAppLifecycle.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;.resumedAppLifecycle&lt;/strong&gt; → True if State object was in a resumed state.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/resumedAppLifecycle.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;add&lt;/strong&gt;() → Add a Controller to this StateX object.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/addAll.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;addAll&lt;/strong&gt;() → Add a list of Controllers to be associated with this StateX object.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/addAll.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;stateByType&lt;/strong&gt;() → Retrieves another State object by its type. Returns null if not found.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/MapOfStateXsMixin/stateByType.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;stateById&lt;/strong&gt; () → Retrieve another State object using its unique String identifier. Returns null if not found.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/MapOfStateXsMixin/statesById.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;controllerByType&lt;/strong&gt; () → Retrieves one of its Controllers by their type.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/controllerByType.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;controllerById&lt;/strong&gt; () → Retrieves one of its Controllers by their unique String identifier.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/controllerById.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  StateXController Class &lt;a&gt;&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;.state → Returns current State object.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/SetStateMixin/state.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;.statex → Retrieves current StateX object.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXController/statex.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;.appStateX → References the App's State object.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXController/appStateX.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;.initStateCalled→ True if initState() was already called.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXController/initStateCalled.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;activateState&lt;/strong&gt; () → Called when this State object is reinserted into the Widget tree after having been removed by deactivate().&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/SetStateMixin/state.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;addState&lt;/strong&gt; () → Associate this Controller to the specified State object. Returns the State Object's unique String identifier.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXController/addState.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;deactivateState&lt;/strong&gt; () → Called whenever the State object was removed from the Widget tree. Passes the 'current' State object parameter.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXController/deactivateState.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;disposeState&lt;/strong&gt; (covariant State state) → The supplied State object will never build again and taken into Flutter's garbage collection.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXController/disposeState.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;initAsyncState&lt;/strong&gt; (covariant State state) → Called with every StateX associated qith this Controller initializing any 'time-consuming' operations needed done at startup.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXController/initAsyncState.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ofState&lt;/strong&gt; )() → Retrieves a currently associated State object by its type T. Returns null if not found.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/SetStateMixin/ofState.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;stateOf&lt;/strong&gt; () → Retrieves an associated State object by its StatefulWidget. Returns null if not found.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/SetStateMixin/stateOf.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Initialization Handlers &lt;a&gt;&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;initAsync&lt;/strong&gt; () → Initialize any 'time-consuming' operations at the beginning. Implement any asynchronous operations needed done at start up.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/initAsync.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXController/initAsync.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;initAsyncState&lt;/strong&gt; () → Called with every StateX associated with this Controller Initialize any 'time-consuming' operations at the beginning. Implement any asynchronous operations needed done at start up.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/initAsyncState.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXController/initAsyncState.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;initState&lt;/strong&gt; () → Initialize anything necessary at the beginning. Implement any asynchronous operations needed done at start up.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/initState.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXController/initState.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;runInitAsync&lt;/strong&gt; () → Call initAsync() all the time if returns true. Conditional calls initAsync() creating a Future with every rebuild&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/runInitAsync.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/runInitAsync.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Event Handling &lt;a&gt;&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;activate&lt;/strong&gt; () → Called when the State object is reinserted into the Widget tree.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/activate.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/activate.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;deactivate&lt;/strong&gt; () → Called when the State object is removed from the Widget tree.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/deactivate.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/deactivate.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;dependOnInheritedWidget&lt;/strong&gt; () → Link a widget to the StateX Object's InheritedWidget.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/InheritedWidgetStateMixin/dependOnInheritedWidget.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXController/dependOnInheritedWidget.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;detachedAppLifecycleState&lt;/strong&gt; () → The Flutter engine has detached the app from view and is shutting down.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/detachedAppLifecycleState.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/detachedAppLifecycleState.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;didChangeAccessibilityFeatures&lt;/strong&gt; () → Called when the current accessibility features have been changed.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/didChangeAccessibilityFeatures.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/didChangeAccessibilityFeatures.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;didChangeDependencies&lt;/strong&gt; () → Called immediately after initState() or when a widget dependent on an InheritedWidget is to be rebuilt.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/didChangeDependencies.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/didChangeDependencies.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;didChangeLocales&lt;/strong&gt; () → Called when the device's locale has changed.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/didChangeLocales.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/didChangeLocales.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;didChangeMetrics&lt;/strong&gt; () → Called when the app's UI dimensions change. E.g. when a phone is rotated.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/didChangeMetrics.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/didChangeMetrics.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;didChangePlatformBrightness&lt;/strong&gt; () → When the device's brightness has changed.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/didChangePlatformBrightness.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/didChangePlatformBrightness.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;didChangeTextScaleFactor&lt;/strong&gt; () → Called when the platform's text scale changes.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/didChangeTextScaleFactor.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/didChangeTextScaleFactor.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;didHaveMemoryPressure&lt;/strong&gt; () → Called when the system is running low on memory.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/didHaveMemoryPressure.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/didHaveMemoryPressure.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;didPop&lt;/strong&gt; () → Called when this State is popped off a route.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/didPop.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/didPop.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;didPopNext&lt;/strong&gt; () → The top route has been popped off returning this State object.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/didPopNext.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/didPopNext.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;didPopRoute&lt;/strong&gt; () → Called when the app pops the current route. E.g. On Android, called when the back button is presse.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/didPopRoute.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/didPopRoute.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;didPush&lt;/strong&gt; () → Called when this State is first pushed as a Route by a Navigator.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/didPush.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/didPush.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;didPushNext&lt;/strong&gt; () → New route has been pushed, and this State object's route is no longer current.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/didPushNext.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/didPushNext.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;didPushRouteInformation&lt;/strong&gt; () → Called when the application pushes a new RouteInformation and a restoration state onto the router.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/didPushRouteInformation.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/didPushRouteInformation.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;didRequestAppExit&lt;/strong&gt; () → Called when a request is received from the system to exit the app. Exiting the app can proceed with [AppExitResponse.exit] response, and do not exit with [AppExitResponse.cancel] response.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/didRequestAppExit.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/didRequestAppExit.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;didUpdateWidget&lt;/strong&gt; () → Called when the State object's StatefulWidget is recreated.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/didUpdateWidget.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/didUpdateWidget.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;dispose&lt;/strong&gt; () → Called when the [StateX] object will never build again and will be taken into Flutter's garbage collection.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/dispose.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXController/dispose.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;handleCancelBackGesture&lt;/strong&gt; () → Called when a predictive back gesture is canceled indicating that no navigation should occur.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/handleCancelBackGesture.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/handleCancelBackGesture.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;handleCommitBackGesture&lt;/strong&gt; () → Called when a predictive back gesture is finished successfully indicating that the current route should be popped.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/handleCommitBackGesture.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/handleCommitBackGesture.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;hiddenAppLifecycleState&lt;/strong&gt; () → The app is about to be paused (on iOS and Android), or has been minimized (Windows) or is no longer visible (on the web).&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/hiddenAppLifecycleState.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/hiddenAppLifecycleState.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;inactiveAppLifecycleState&lt;/strong&gt; () → The app is in an inactive state and is not receiving user input.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/inactiveAppLifecycleState.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/inactiveAppLifecycleState.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;pausedAppLifecycleState&lt;/strong&gt; () → The application is not currently visible to the user, not responding to user input, and running in the background.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/pausedAppLifecycleState.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/pausedAppLifecycleState.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;reassemble&lt;/strong&gt; () → Called when the app is reassembled during development, E.g. A hot reload.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/reassemble.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/reassemble.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;resumedAppLifecycleState&lt;/strong&gt; () → The app has returned from the background. Is now visible and ready for user input.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/resumedAppLifecycleState.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/resumedAppLifecycleState.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;setState&lt;/strong&gt; () → Call build() function of the State object in the next frame cycle.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/setState.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXController/setState.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;updateShouldNotify&lt;/strong&gt; () → As a dependency of an InheritedWidget, return true to rebuild the State object.&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateX/updateShouldNotify.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/updateShouldNotify.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Error Handler &lt;a&gt;&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;onError&lt;/strong&gt; () &lt;strong&gt;→&lt;/strong&gt; Offer an error handler&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXonErrorMixin/onError.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/onError.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;onAsyncError&lt;/strong&gt; () &lt;strong&gt;→&lt;/strong&gt; In case the initAsync() function has failed in error. This must be handled too. &lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/onAsyncError.html" rel="noopener noreferrer"&gt;StateX&lt;/a&gt;|&lt;a href="https://pub.dev/documentation/state_extended/latest/state_extended/StateXEventHandlers/onAsyncError.html" rel="noopener noreferrer"&gt;StateXController&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;catchAsyncError&lt;/strong&gt; () &lt;strong&gt;→&lt;/strong&gt; Catch it if &lt;strong&gt;initAsync&lt;/strong&gt; () throws an error. Return true to indicate the error handled. Return false to continue the error handling StateX|StateXController&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Next article will cover the following topics:&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Event Handling
&lt;/h3&gt;

&lt;p&gt;Remember, if not addressed, the example app's Timer will always be running taking up valuable CPU cycles even when those red Wordpairs are no longer in view. There are event handlers available to the StateX class to address such considerations. The screenshots below and see the Timer is actually terminated when moving off Page 1. Nice.&lt;br&gt;
The &lt;strong&gt;didPushNext&lt;/strong&gt;() method is called when the 'next route' is pushed from this current State object. Note, the _&lt;strong&gt;cancelTimer&lt;/strong&gt;() is called terminating the Timer before the Page 2 screen is displayed. Also, if there's an error, you can see the Timer is terminated in the &lt;strong&gt;onError&lt;/strong&gt;() method. Very nice.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F624%2F1%2AaShPUKwwMK0NdElcNAczUw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F624%2F1%2AaShPUKwwMK0NdElcNAczUw.gif" width="1024" height="1024"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F07k2fbiv0hwmzkecxaw0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F07k2fbiv0hwmzkecxaw0.png" width="800" height="700"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/controller/word_pair_timer.dart#L139" rel="noopener noreferrer"&gt;word_pair_timer.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj2ag5pglu12prxyd5w03.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj2ag5pglu12prxyd5w03.png" width="590" height="1250"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe0o8ipw9gkpgsuvb9xgy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe0o8ipw9gkpgsuvb9xgy.png" width="800" height="693"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a&gt;page_01.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F624%2F1%2AiHILCM-DhBLrnnvDYGfkdg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F624%2F1%2AiHILCM-DhBLrnnvDYGfkdg.gif" width="1024" height="1024"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9r0tq6a8o7ockjnmjuol.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9r0tq6a8o7ockjnmjuol.png" width="800" height="824"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff920g265j1ovs8zvytj1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff920g265j1ovs8zvytj1.png" width="581" height="411"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxf52puvwqgrc53wsaacx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxf52puvwqgrc53wsaacx.png" width="800" height="698"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/lib/home/controller/word_pair_timer.dart#L123" rel="noopener noreferrer"&gt;word_pair_timer.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq6tb0ew1gua768kucdvz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq6tb0ew1gua768kucdvz.png" width="800" height="699"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/lib/part01_statex.dart#L955" rel="noopener noreferrer"&gt;pat01_statex.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdrncthdpk4pu401pi8gb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdrncthdpk4pu401pi8gb.png" width="800" height="698"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/lib/part01_statex.dart#L970" rel="noopener noreferrer"&gt;part01_statex.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  Testing Your App&lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;If I were you, a great way to get to know StateX would be to step through its accompanying &lt;a href="https://github.com/AndriousSolutions/state_extended/tree/master/example" rel="noopener noreferrer"&gt;test files&lt;/a&gt; that run whenever a new version of its package is pushed up to its GitHub &lt;a href="https://github.com/AndriousSolutions/state_extended" rel="noopener noreferrer"&gt;repository&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The screenshots below give an idea of what will be covered in the next article.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F624%2F1%2AUcZGDiQqdqX0UDwfY5QBRg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F624%2F1%2AUcZGDiQqdqX0UDwfY5QBRg.gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo3oh20ch0190xd3ka3ky.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo3oh20ch0190xd3ka3ky.png" width="800" height="691"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/test/widget_test.dart#L99" rel="noopener noreferrer"&gt;test_widget.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flgfnkpx137aa8lcuq31g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flgfnkpx137aa8lcuq31g.png" width="800" height="692"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/integration_test/_integration_testing.dart#L16" rel="noopener noreferrer"&gt;intergration_testing.dart&lt;/a&gt;



&lt;h3&gt;
  
  
  Unit Testing &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9db2lhl4124vvggmwsra.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9db2lhl4124vvggmwsra.png" width="800" height="700"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/test/test_app_state.dart#L16" rel="noopener noreferrer"&gt;test_app_state.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwp2a04jepbk8p6oqtr1w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwp2a04jepbk8p6oqtr1w.png" width="800" height="695"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/test/test_statex.dart#L17" rel="noopener noreferrer"&gt;test_statex.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwdogdc9hd26rnpbq9g8q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwdogdc9hd26rnpbq9g8q.png" width="800" height="685"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/test/test_statexcontroller.dart#L13" rel="noopener noreferrer"&gt;test_statexcontroller.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F47hpvvohw6yshv9jb13j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F47hpvvohw6yshv9jb13j.png" width="800" height="696"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/test/test_run_mixins.dart#L12" rel="noopener noreferrer"&gt;test_run_mixins.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffpkrg0n42zjxmq9r3818.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffpkrg0n42zjxmq9r3818.png" width="800" height="695"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/test/test_event_handling.dart#L97" rel="noopener noreferrer"&gt;test_event_handling.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi21qm493nbl6pgetafs8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi21qm493nbl6pgetafs8.png" width="800" height="696"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/test/test_event_handling.dart#L137" rel="noopener noreferrer"&gt;test_event_handling.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F086qnya57tgz1t3i22ug.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F086qnya57tgz1t3i22ug.png" width="800" height="691"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/test/test_event_handling.dart#L11" rel="noopener noreferrer"&gt;test_event_handling.dart&lt;/a&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0pvavajtufou220oxne9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0pvavajtufou220oxne9.png" width="800" height="698"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/AndriousSolutions/state_extended/blob/a8fa0892ecd357178a5eaafbcc32fc55b507e23c/example/integration_test/reset_page1_count.dart#L11" rel="noopener noreferrer"&gt;reset_page1_count.dart&lt;/a&gt;



</description>
      <category>programming</category>
      <category>flutter</category>
    </item>
  </channel>
</rss>
