avatarMehmet Fidanboylu

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

2311

Abstract

May</li><li>preparing an application for a coaching certification</li></ul><p id="f352">All of these tasks were stimulated by the productivity urge.</p><p id="d2f7">I was overloading myself. Also, I noted with more than a hint of regret that many of these quests to be productive were putting undue pressure on others to be productive too.</p><p id="cd85">It was time to be <i>less productive</i>.</p><p id="fb98">I set about culling my list.</p><h1 id="47d5">Forgiveness</h1><p id="fbe1">Let’s be real for a second. There’s a pandemic out there. We’re all in quarantine. A lot of people have lost their jobs and even those of us lucky to still be working have all but lost the structure to our days and weeks.</p><p id="dc2f">News cycles are punishing. Everything takes more effort. Energy levels are low. Mood can be low too. It is not a time to overload: it is a time for self-care.</p><p id="4f3b" type="7">That can actually mean doing less. And that is ok.</p><p id="3467">I began cancelling things. I cancelled the webinar on remote working. My friend who was organising it with me immediately said thank you.</p><p id="1f94">I postponed the second work-related webinar. Two work colleagues agreed it was a good idea.</p><p id="09b7">Launching the new Medium Publication is still an ambition, but I am taking my foot off the gas with that. It can happen later in the year. I forgive myself.</p><p id="0812">I am also taking the pressure off myself to write at all. I still get huge enjoyment out of writing for Serious Scrum, but my inspiration is lower, and that is ok: it always ebbed and flowed. I forgive myself for my lower rate of publication.

Illumination is a new project for me. I have no idea how much I will write here and, you know what, I forgive myself for that uncertainty as well.</p><p id="e954">Writing this feels confessional and unusual for me. It is not how I normally write. But it feels good. As I write, I forgive myself for over-sharing.</p><p id="4a1d">I hope others will recognise something in my story and perhaps begin to forgive themselves for doing less too.</p><h1 id="87bd">Distraction</h1><p id="a2be">It’s probably fair to point out: I didn’t cancel <i>everything</i>.</p><p id="e2c4">The meet-up in May was a request from a friend and the topic is one I’ve written ab

Options

out already, so I’m going to continue with that. My friend did ask me this weekend if I was still ok to do it, and I had an opportunity to say no. For once, I didn’t automatically dismiss the idea of saying no. I forgive myself for thinking about saying no.</p><p id="0f00">Also, I continue to be inspired to apply for a coaching certification. This is a long-term ambition of mine, and there is no time-sensitivity to the application process. I choose to take that pressure off myself now, and I also choose to forgive myself for taking my own sweet time with it.</p><p id="d7b2">I allow myself these distractions because they are meaningful to me.</p><p id="53ec">Also, without the overload of other tasks, I can do these at a pace that makes more sense to me.</p><figure id="20f5"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/0*IiUm2PXzVt6r4zhg"><figcaption><b>Flight Safety Instructions</b></figcaption></figure><h1 id="e2b3">Moving forward, one step at a time</h1><p id="9703">You do not <i>have to</i> be productive.</p><p id="c7d3">You need to care for yourself so that you can care for others. Watch out for the to-do list and that feeling of being a little overwhelmed. It can creep up on you.</p><p id="9383">Forgive yourself for taking on less. It’s ok.</p><p id="2b1a">Forgive yourself for your low energy. It’s ok.</p><p id="4d89">Forgive yourself for your low mood or for those days when you don’t want to do anything at all.</p><p id="5160">It’s ok to not be ok.</p><p id="b459">Flight safety instructions tell us:</p><blockquote id="a104"><p>“If you are travelling with a child or someone who requires assistance, secure your mask on first, and then assist the other person.” (Source: <a href="https://activerain.com/blogsview/2535480/put-your-own-oxygen-mask-on-first">Active Rain</a>)</p></blockquote><p id="0be5">Self-care means that, rather than feeling pressured to be more productive, you might need to go out for a walk instead.</p><p id="45ff">By taking on less and looking after yourself, you will put your figurative oxygen mask on. This will help you to breathe better.</p><p id="5277">First things first. Breathe.</p><p id="8085">If you can, cancel the things you don’t need to do right away.</p><p id="5e33">It’s ok. You can forgive yourself.</p></article></body>

Inheriting Widgets

Flutter widget trees can be deep…

Very deep.

The composable nature of Flutter widgets lends itself to very elegant, modular and flexible app design. However, it can also lead to a lot of boilerplate code for passing context around. Watch what happens when we want to pass accountId and scopeId from the page to a widget two levels below:

If not kept in check, this pattern can spread very easily throughout your code base. We had over 30 widgets being parameterized this way. Nearly half the time, the widget was receiving parameters just to pass it along, just like the MyWidget example given above.

MyWidget’s state is independent of the parameters and yet it was getting rebuilt every time the parameters were changing!

Surely, there must be a better way…

Enter InheritedWidget.

In a nutshell, this is a special kind of widget that defines a context at the root of a sub-tree. It can efficiently deliver this context to every widget in that sub-tree. The access pattern would look familiar to Flutter developers:

final myInheritedWidget = MyInheritedWidget.of(context);

This context is just a Dart class. As such, it can contain anything you care to put in there. Many of the frequently used Flutter contexts such as Style or MediaQuery are nothing but inherited widgets living at the MaterialApp level.

If we augment the example above using inherited widgets, here’s what we get:

It is important to note:

  • The constructors are now const making these widgets cacheable; thus increasing performance.
  • When the parameters get updated, a new MyInheritedWidget is built. However, unlike the first example, the subtree is not rebuilt. Instead, Flutter keeps an internal registry that keeps track of widgets that have accessed this inherited widget and only rebuilds widgets that use this context. In this example, that is MyOtherWidget.
  • If the tree gets rebuilt due to a reason not related to the parameters such as orientation change, your code can still build a new inherited widget. However, since the parameters are the same, widgets in the sub-tree would not be notified. This is purpose of the updateShouldNotify function implemented by your inherited widget.

Finally, let’s talk about good practices:

Keep inherited widgets small Overloading them with a lot of context ends up costing you the 2nd and 3rd advantage mentioned above since Flutter cannot detect which part of the context is updated and which part the widgets are using. Instead of:

Prefer doing:

Use const to build your widgets Without const, selective rebuilding of the sub-tree does not happen. Flutter creates a new instance of each widget in the sub-tree and calls build() wasting precious cycles especially if your build methods are heavy.

Properly scope your inherited widgets Inherited widgets are placed at the root of a widget tree. That, in effect, becomes their scope. In our team, we found that the power to declare context anywhere in the widget tree is a bit too much. So, we restrict our context widgets to accept only Scaffold (or its derivatives) as a child. That way, we ensure the most granular context can be at the page level ending up with two types of scope:

  • App-scoped widgets such as MediaQuery. These are accessible by any widget on any page in your app since they sit at the root of your app widget tree.
  • Page-scoped widgets such as the MyInheritedWidget in the example above.

You should choose one or the other depending on where the context is applicable.

Page-scoped widgets cannot cross route boundary

This one seems like a no-brainer. However, it has profound implications because most apps have more than one levels of navigation. This is what your app could look like:

This is what Flutter sees:

From Flutter’s perspective, a navigation hierarchy does not exist. Each page (or scaffold) is a widget tree tied to the application widget. Therefore, when you use Navigator.push to display these pages, they do not inherit the widget carrying parent’s context. In the example above, you will need to pass the Student context from Student page to Student Bio page explicitly.

Although there are different ways to pass context, I suggest parameterizing your routes the old-fashioned way (such as URL style encoding if you use named routes). This also ensures the pages can be constructed solely from the route without needing the context from their parent page.

Happy coding!

Flutter
Recommended from ReadMedium