Modern Frontend Architecture 103
By: Bilel Msekni
Tags: Software Engineering, Front End Development, Vuejs, Angular, React

Understanding what matters, away from Javascript fatigue and framework wars

In the Modern Front End Architecture 102 post, we talked about the three layers of feature architecture. One of them is the state management layer which we take a deeper look at today. Without further ado, here is the third and last part of the introduction to modern front end architecture serie.

State management, you may not see it but it is somewhere there ..

Let’s imagine we have a shopping App with a list of products. When the user selects a product, its details (price, origin, ..etc) are displayed. Perhaps, it is just a click of a button for most users but for a frontend developer, the App state has changed. What does this means ?

Let’s review what really happened step by step:

A user performed a click event to select a product.

The App reacted to the event by fetching the details of the product.

The UI is updated to reflect the new value of the product details.

So, whenever an event happens, the App updates its values then displays the change.

So what is state ?

The values held by the application as properties or variables at any given time Source: Quora

Then what is state management ?

The concept of adding, updating, removing and reading pieces of state in an application

Ok, how does it impact frontend Architecture ?

Frontend applications are conceived of functions dispatching events that change the current state to another which will be reflected by the UI.

Component and state interactions

To render properly, components need inputs which are usually provided by the state. This means that any change to the state updates the inputs therefore change detection should be triggered to refresh the view.

So the question is, how to change the state ? 🤔

Let’s answer the question by exploring the Redux pattern (currently the de facto standard for frontend state management).

When an event (click, drag, HTTP call, ..etc) occurs in the application, it is translated to an action that gets dispatched to the state management realm. Upon arrival, it is processed by functions known as reducers. They are pure functions responsible for creating a new state using the incoming action and the current state. The new state replaces the current one and the component inputs get updated according to the new values.

Inside Redux

A pure function means that you always get the same output for the same inputs. This leaves no room for side effects that can make the result unpredictable. For instance, the sum of two values will always be the same (1 + 1 = 2) but a network request may or may not succeed for different reasons (network, bad request, authorization, ..etc).

So how to handle side effects in Redux ? 😵

Inside advanced Redux

Exactly the same way as described earlier, except that actions triggering tasks with side effects do not get processed by the reducers but by another part of Redux. The side effects handler executes the impure task then re-introduces the result as an action with no side effects. For instance, when “Fetch product details” action is dispatched, the side effect block will make an HTTP call to retrieve the results. Once the call is finished (successfully or with a failure), a new action describing the final result (Fetch product details success or Fetch product details failed) gets sent to the reducers.

The state management block is known as the Store in Redux. It dispatches actions, contains the reducers and stores the current state. The Redux pattern enforces a unidirectional data flow that makes Apps predictible and consistent. It’s only through actions that the App state can evolve and that evolution will be reflected by the UI.

How can all of this impact our code structure? 🤓

AppRepo

│

├──/Overview

| ├──/Components

| ├──/ListComponent

│ └──/ChartComponent

| ├──/State

| ├──overview.state.ts * our feature state file

| ├──overview.actions.ts * our feature actions file

| ├──overview.reducers.ts * our feature reducers file

Following the same approach taken for components, we decided to create a folder to host every element belonging to the state management layer:

feature.state: The definition of the feature state

The definition of the feature state feature.actions : The actions belonging to the feature business domain

: The actions belonging to the feature business domain feature.reducers: The functions with the necessary logic to update the feature state

Explaining software architecture is no easy task

I tried to adopt an outside in (top to bottom) approach where I walked through how Apps are made of different building blocks in the Modern front end architecture 101 post. Later, I pointed out how feature architecture is made of three layers separated by concerns in the Modern front end architecture 102 post. Finally, I wrote about the insides of the state management layer and its impacts on the front end App.

There are still more challenges about front end architecture like monorepos, micro frontends or just how to keep functional domains well seperated yet understandable but in my opinion, it all starts by understanding the nature of front end applications and its requirements.

I hope you enjoyed reading my articles and don’t forget to 👏 🙌 👋!