Flux pattern: The definition, elements and how to implement it in React applications

As our applications get bigger and more complex, we certainly need a better data handling approach. With more data, we’ll have more to keep track of. So, if you have started working on React recently then you might be wondering how to manage state in React so that your application can scale. To clarify, in order to solve this state management issue, many companies and people have developed various solutions. And that’s when Flux pattern comes to existence.

Flux - a complete guide
Flux pattern – a complete guide

From asynchronous server responses to locally-generated, unsynchronized data, Flux pattern can not only help us keep track of this data but also tie it to the view in a sane way. So in this article, we – ArrowHiTech will walk you through everything you might need to know about this pattern, and how to implement them in React applications. You might also get something out of it if you already know the basics of this pattern and are looking to gain a deeper understanding.

But first, let’s see some definitions.

What is Flux pattern?

Flux pattern uses a unidirectional data flow pattern to solve state management complexity. As we’ve seen before, the preferred method of working with React components is through passing data from one parent component to its children components. Yet, it is not a framework – rather it’s more of a pattern that targets to solve the state management issue.

To clarify, there are four distinct roles for dealing with data in the pattern’s methodology:

  • Action
  • Dispatcher
  • Stores
  • Views 

The major idea behind this pattern is that there is a single source of truth (the stores) and certainly, they can only be updated by triggering actions. The actions are responsible for calling the dispatcher, in which stores can subscribe for changes and update their own data accordingly. While React makes uses of a virtual DOM object to render changes, Flux pattern does it differently. In this pattern, the interactions with UI will trigger a series of actions that would alter the application data.

The elements of Flux pattern

As mentioned above, there are four distinct elements in this pattern’s methodology. This may seem unnecessarily complex, but the structure makes it incredibly easy to reason about where our data is coming from, what causes its changes, how it changes and lets us track specific user flows, etc. Let’s go to the details.

The element of this pattern

#1. Action

This handles all the events. These events are passed by the view component. This layer is generally used to make API calls. Once the action is done it is dispatched using the Dispatcher. The action can be something like add a post, delete a post or any other user interaction. All in all, this process of Flux pattern help pass data to the Dispatcher.

#2. Dispatcher

The Dispatcher is basically the manager of this entire Flux pattern process. It is the central hub for your application. That is to say, the dispatcher receives actions and dispatches the actions and data to registered callbacks. It broadcasts the payload to all of its registered callbacks and includes functionality while allows you to invoke the callbacks in a specific order. There is only ever one dispatcher, and it also acts as the central hub within your application.

Let’s see a small example:

 
var Dispatcher = require('flux').Dispatcher;
var AppDispatcher = new Dispatcher();
AppDispatcher.handleViewAction = function(action) {
  this.dispatch({
    source: 'VIEW_ACTION',
    action: action
  });
}
module.exports = AppDispatcher;

In the above example, we create an instance of our Dispatcher and create a handleViewAction method. All in all, this abstraction is helpful if you are looking to distinguish between view triggered actions v.s. server/API triggered actions. The Flux pattern method will broadcast the action payload to all of its registered callbacks. This action can then be acted upon within Stores, and will result in a state update.

#3. Stores

This holds the app state and is a data layer of this pattern. Do not consider it as a model from MVC. An application can have one or many app stores. Stores get updated because they have a callback that is registered using the dispatcher. Node’s event emitter is used to update the store and broadcast the update to view. Also, the view never directly updates the application state. It is updated because of the store’s changes. As a result, this is the Flux pattern’s only part that can update data.

#4. Views

The View propagates the Action through a central Dispatcher and this will be sent to various Stores. These Stores would certainly contain an application’s business logic and other data. It updates all the Views, and also works best with React’s programming style and the Store sends updates without the need to detail how to transition views between states. As a result, this proves that the Flux pattern follows a unidirectional data flow. 

These views are directly hooked into stores and are listening for the change events triggered when the stores are updated. When this happens, controller views call the setState method, which triggers the render() method to run and update the view and send data to child components through props. From there, React and the Virtual DOM do their magic and update the DOM as efficiently as possible.

How to implement the flux pattern in React applications?

We’ve been going through a lot of detailed information, and it’s time to put them together. In this last section, we’ll review the entire flow from actions to views and fill in the missing code needed to complete Flux pattern’s unidirectional data flow.

Dispatching an Action

Getting back to the <AddNewItem /> component, you certainly can include the WalletActions module and use it to generate a new action in the _addNewItem() method.

  import React from 'react';
import WalletActions from '../actions/walletActions';
// …
_addNewItem(event) {
    event.preventDefault();
    this.state.item.description = this.state.item.description || '-';
    this.state.item.amount = this.state.item.amount || '0';
    WalletActions.addNewItem(this.state.item);
    this.setState({ item : this._getFreshItem() });
}
// …

Now, when the form is submitted, an action is dispatched and all stores – one in our case – are notified about the new data.

Listening for Store Changes

In your WalletStore, currently, when an item is added to the list its state changes, and the change event of Flux pattern is triggered, yet no one is listening. So, let’s close the loop by adding a change listener inside the <ItemsList /> component.

  import React from 'react';
  import WalletStore from '../stores/walletStore';
  class ItemsList extends React.Component {
      constructor(props) {
          super(props);
          this.state = {
              items: WalletStore.getAllItems()
          };
          this._onChange = this._onChange.bind(this);
      }
      _onChange() {
          this.setState({ items: WalletStore.getAllItems() });
      }
      componentWillMount() {
          WalletStore.addChangeListener(this._onChange);
      }
     componentWillUnmount() {
         WalletStore.removeChangeListener(this._onChange);
     }
     render() {
         // ...
     }
 }
 export default ItemsList;

The updated component closes Flux pattern’s unidirectional data flow, so note that we skipped including the entire render() method to save some space. Let’s go step by step through what’s new:

  • The WalletStore module is included at the top.
  • The initial state is updated to use the store’s state instead.
  • A new _onChange() method is used to update the state with the new data from the store likewise.
  • Using React’s lifecycle hooks, the _onChange() callback is also added and removed as the store’s change listener callback.

Final words

Above all, as you can see, this article is everything you may need to know about Flux pattern, and also how to implement this pattern into React applications. After reading this article, I hope that if you didn’t “get” Facebook’s Flux Architecture before, that now you can say you do. It wasn’t until building something with it that I understood how complimentary to React.js it actually is. Moreover, if you have any question of this topic, let’s CONTACT US to be more clearer.


Tags

Share