Double Flux – Separating UI State from Application State

With React, and Flux we seem to go back to the roots. Implementations get more explicit. Application architectures get simpler again.

Maybe a bit too simple? Or not simple enough?

The Flux architecture…

… in as little words as possible: UI triggers action, action changes state, state change triggers UI update. Flux

The nice thing about Flux is that state handling in the UI is almost not necessary. So when writing components in React that just represent state you should never need to call

anywhere. This makes the component implementation simple and easy to understand.

When do we need UI state?

The only time you need to manage UI specific state is for unfinished user interactions, that are not ready to update application state. An input field for example that waits for the user to hit enter to submit has to store an intermediate state. In React you normally do that using either a controlled or an uncontrolled component. In a controlled component I used to store the state in the component itself using this.setState.

What is feasible for simple form fields can get quite complicated for more complex user interaction where multiple components together use the intermediate state of the UI.

Propagating state from component to component can become alot of work and at least for me always turned into some messy code. Props passed from component to component and callbacks to send messages up to parent components. It defeats the simplicity Flux and React propagate.

So I started to store the intermediate state in my applications store as well. Somehow that felt wrong. I mixed my business model with UI state. No separation of the UI from the model, because how the store represents that intermediate state can depend on the UIs implementation.

There must be a better way. So lately I’m experimenting with the following idea.

Two Fluxes, one for the Application and one for the UI

As quite someĀ  people do, I am writing my own Flux implementation called fluss. It’s still early in development. Lately while converting from Typescript to ES6 I removed the singleton feature for the dispatcher/store (fluss is a bit different here) and called it a Domain.

The domain now manages state (the store) and the logic that manipulates the state (implementation of actions). Since it is not a singleton you can have multiple instances of such a domain: One for the application (business logic) and one for the UI. Perfect separation.




Let’s create a very simple example. The app provides an input field. The user can type stuff. When he/she hits enter the value of the input field will be added to a list.

I will use ES6 and React.


Application Domain – The Business Model

The “business” model is simple: Manage a list of values. So let’s create a domain for that.

The application domain will be a singleton for our application. And it needs an action to add a new value to it.

This is all there is to it. Actions in fluss are just IDs. The domain then maps implementations of behavior to those IDs. That’s what app.wrap does. Fluss.Actions.enumerate just makes all IDs unique. I do it in two lines so Webstorm gives me code completion for the action IDs.

Displaying the Values

Displaying the values is straight forward. We do it directly in an application component.

Render the application

Now lets render the application.

In order to display something we use the action newValue to create a new value in our business model.

Interaction – Get me that input field

We’ll use a controlled component to implement the input field.

The render method is nothing special. The interesting parts are the two event handlers.

handleChange will be called whenever the value of the input field changes because of user interaction. We call some UI.updateInput-function on that. What’s that?

Same with handleKeyDown. We call UI.submitInput whenever the user hits enter. We don’t pass a value.

Interaction state – the UI domain

The two functions we call in the event handlers of the input field are actions of the UI domain. That domain is our second Flux in the application.

The domain object again is very simple. It stores one value in a record.

It will be a single instance again for our application and defines two actions. One that updates the state with the current value of the input field and one that passes the current value of the state to our business model.

See how UI state behavior is defined in the UI domain and not the UI component. The SUBMIT_INPUT action clears the inputValue after submitting it (line 14). If we were to implement error handling here we could just leave the value for the user to change.

Adding the Input field

Now we extend our startup function to create the UI domain…

… and the Application component to display the input field and utilize the UI domain

In componentDidMount we then update the AppComponent for all changes in both stores.

Now the app works as intended. We can type in the input field and when we hit enter, our text will be added to the list.


Central UI state – the benefit

Up until now it may seem to be quite a hassle for such a simple application. So what’s the benefit? Adding new components that represent UI state as well is plain simple now!

In line 16 we simply added two components that use the UI state or its actions.

And it just works. The three components that use the UI state are completely independent.


Reusability – The Input component is coupled to the UI domain

This can be fixed easily. If you build all your components this way, an interactive component defines two things

  • The data it displays/uses
  • The actions (events) it will trigger during interaction

For our input field these actions are: updateInput and submitInput.

When using the component we pass it the actions of the UI domain.

The Result

The app works as intended and by separating the UI state from the application state we got a very simple solution that is extensible both on the UI and the business logic.

You can find the complete application on github:


I came up with this when writing an application where the user is able to connect nodes graphically. My data basically consists of two lists: The nodes and the connections. I had two problems with that app: How does the connection know where the nodes are on the screen (subject to layout, scaling, etc.) and how do I draw the unfinished connection the user is just creating?

Using the two domains solved that nicely for me. Fluss itself is a bit rough around the edges especially when defining the actions, but I already start liking to work with it. There are other implementations of Flux that can be used this way, e.g. flummox.

So I think this could be a route to follow, especially for complex user interactions. What do you think?

ES6 in Webstorm 9 – Setting up a file watcher for Babel

Webstorm supports ES6 for several versions now and uses Traceur as the standard transpiler. With the latest developments to 6to5, now called Babel, here’s how to setup a file watcher for it.

ES6 syntax support

Webstorm supports the new syntax features for ES6 but they are not activated by default. Open the settings dialog and search for javascript. Under Languages & Frameworks you find the settings to enable ECMAScript 6 support.

Enable ES6 support

Register the .es6 extension

By default file watchers in Webstorm compile the file inplace, i.e. you’ll have your compiled file and the sourcemap right next to your original ES6 file. To avoid name clashes you should use a different filename extension. .es6 seems like a good choice.

In the settings dialog search for filetypes. You could create a completely new filetype “ECMASCript 6″ now, but it seems you cannot assign a syntax highlighting to that. Webstorm will do ES6 syntax highlighting to all Javascript files so we simply add the new extension *.es6 in the Patterns section for Javascript files. Apply.

Add the es6 extensions for Javascript files

While we’re at it let’s create a new file template for ES6-files so we can quickly create new files in the project structure. Search for templates in the settings dialog

Setup an ES6-File template

Create a new template named ES6-File and set the Extension and the code template accordingly.

Setting up the file watcher

Now we can setup the file watcher. As described before, the file watcher will compile your files inplace. Webstorm does this nice thing where it hides the generated files “beneath” your source file whenever they are created by a file watcher. In my experience this will not work for a file watcher created from scratch so we will copy an existing one. I found that copying the Traceur watcher does not work but copying the Typescript watcher does work.

In the settings dialog search for file watcher.

Search for file watchers

Now let’s copy an existing one. Click the plus icon and choose Typescript.

Copy the Typescript settings

In the following dialog we now change the settings to use Babel instead of the Typescript compiler.

Create the new watcher

Change the Name and the Description to something meaningful. Set the File type to Javascript.

Next you need to set the correct Program setting to call the babel compiler. For Windows it is

Now we set the Arguments so that babel will output to a file and create sourcemaps

This will create a .js-file with the same name and an according sourcemap.

You should turn off Compile main files only. The Typescript compiler can resolve all necessary files from one main file and transpiles them all. Babel does not do that, as far as I am aware. If you want Immediate file synchronisation is up to you. I normally turn it off.

We’re almost done. If you’d leave the settings like this, the next code change to an ES6-file would send the file watcher into an infinite loop. The file watcher works on Javascript files. Since .es6 files are Javascript files it will correctly compile your ES6 files. But .js files are Javascript files as well so the file watcher will compile the .js-file it just created into the same file over and over again. To avoid that we need to define a scope on which the file watcher should work.

So click the next to the dropdown for the Scope and create a new custom scope.

Define a scope for es6 files

Give it a descriptive name and set the pattern to

This will match all *.es6 files in you project.

Now make sure that your new custom scope is used for the watcher and you’re done. If you edit an .es6 file the file watcher will automatically compile your code into ES5 Javascript and create a source map. In the project structure the generated files are nicely hidden underneath your original file to give you an uncluttered view on your code base.


Reusing the file watcher

Within the file watcher dialog you can save the settings to reuse them later projects. Simply export your settings. You can then later import them into another project.

exportNow have fun with ES6!