Effective Application State Management - Lesson 1

Reading Time: 4 minutes

Preliminary

I'm back! I haven't abandoned this blog, but I procrastinated too much, without being inactive at all. I'm full of cool ideas and have some projects running, e.g. building an Arcade Machine, learning Elixir/Phoenix. I think/hope that in 2017 I'll have more time to write more articles...and this is the first one of a series which I call "Effective Application State Management", based on the concept of Scott Meyers "Effective C++".

Introduction

Since I discovered ReactJS more than two years ago, the way I develop web application has changed significantly. Although, I consider ReactJS as an easy-to-learn-and-use-library, I have to admit that managing complexity of a large app is quite challenging. This has nothing to do with ReactJS itself, but more with the applications architecture. Usually, at this point we start talking about Flux/Redux/MobX, or whatever, but I generalize it and talk about Application State in general. A few months ago I developed nanoflux and nanoflux-fusion, yet another Flux implementation, and so I got deeper into state management, and gained some cool insights. Futhermore, I encountered several issues with application states during my daily work. I had a lot of discussions with colleagues and customers about how to do certain things. Interestingly, most doubts were somewhat related to state management. So, I came up with the idea to make a series of articles related to "Application State Management". The articles are structured as small lessons, like Scott Meyers did in his famous books. They won't favor any kind of library, nor client or server-side, nor web, or desktop; but most times the lessons apply very well for component based applications, as it is state-of-the-art in web development. For sake of understanding, I use a ReactJS/JSX like pseudo-code in the example, as I assume that the reader is somewhat familiar with it, and even if he is not, the notation is quite concise and comprehensive.

If you don't know exactly what I mean by application state just follow the series. Additionally, you may have a look at this fun-project here to get a slightly better idea how state management can be easily realized. Hopefully, you'll get an understanding of it 🙂

- Let's start with the first lesson

First Lesson - Keep your state as simple as possible

Often, I realize that a state is used to compute another state of it. "Wtf, you're talking about?", you may ask. Ok. I'll show you a very common case

render(){
   return (
       this.state.userRole === 'admin' ?  : <AdminComponent/> : <UserComponent/>
   )
}

The state userRole is used to compute a state which could be named userIsAdmin, such that the above code would look like this

render(){
   return (
       this.state.userIsAdmin ?  : <AdminComponent/> : <UserComponent/>
   )
}

That way you eliminate redundant (business) logic. It is much less pain to react on future changes of the logic. Suppose, that the role name changes one day from 'admin' to 'administrator', so you have to track down all occurrences in the code and change your logic. In large apps this can be up to several dozen or even more places. And afterwards you have to test it...Bah!

The depicted case is in fact an easy-to-decide one, but sometimes it's not that easy. Imagine a shopping cart component, which updates each time a new product is added.

render(){
   function calculateTotalCost(items){
      return items.reduce( (p,item) => p+(item.price*item.quantity), 0.0).toFixed(2);
   }

   return (
       <div>
          <CartItemList items={this.state.cartItems}/>
          <div className='cart-total'>{calculateTotalCost(this.state.items) + '$'}<div/>
       <div/>
   )
}

As long as the total cost calculation is only inside the shopping cart component, I wouldn't introduce any total cost state. As a rule of thumb I use the DRY-principle. If I need a state in more than one place then I consider to extract it, i.e. introduce a new state.

Ok. This was the first lesson. Continue with next lesson.

 

Facebooktwittergoogle_plusredditpinterestlinkedin

Leave a Reply

Your email address will not be published. Required fields are marked *