CHAPTER 5

image

Introducing Flux: An Application Architecture for React

The first four chapters of this book introduced React, which is the JavaScript framework for creating user interfaces, a product of Facebook’s engineering team. What you have seen up to this point is sufficient to create robust user interfaces using React and to implement React into your new or existing application frameworks. However, there is more than just React to the React ecosystem. One of these items is Flux, an application framework created by Facebook to complement React in a way that displaces the standard Model-View-Controller (MVC) framework. This is not because there is necessarily anything wrong with MVC as it stands, but more because when you start building an application with React and dissecting your application logic into components, you will find that a framework, similar to the typical MVC, will not be as efficient or maintainable as something like Flux, which has been designed with React in mind and also has the ability to scale your application without an increasing maintenance cost.

This chapter will outline what Flux is and how to get started with Flux, and also explores how Flux and React fit together. You will become familiar with the Flux concepts before structuring an application with Flux in the following chapter.

What Flux Is and Why It Is Different than Typical MVC Frameworks

Flux is purpose-built for React. It is an application architecture meant to eschew the concept of multi-directional data flow and binding, which is common in typical MVC frameworks. It instead offers a unidirectional data flow where React is the user interface layer in the middle. To get a better example, let’s examine the typical MVC framework and look at the problems that arise when attempting to scale an application beyond its designed capacity.

In Figure 5-1, you see that there is direction that starts from an action and passes through the controller to the model.

9781484212462_Fig05-01.jpg

Figure 5-1. Typical Model-View-Controller data flow model

The Model and View can swap data back and forth. This is relatively straight-forward, but what happens if you add a few extra models and views? Then it becomes a little more complex but still something you can handle, as outlined in Figure 5-2.

9781484212462_Fig05-02.jpg

Figure 5-2. Additional models and views added to the MVC data model

This is clearly more complex because there are multiple views and models, some of which even share data between one another. However, this structure doesn’t get completely unwieldy until there are so many models and views that you can no longer track the dependencies even in a simple model diagram, let alone figure out how the models and views interact with one another within the code itself.

What you see when it starts to become unwieldy is the same scenario that leads us to move toward React in the first place. The nesting and coupling of these dependencies causes you to have ample opportunities in which to lose track of a particular variable or relationship. This means that updating a single model or view could have detrimental effects to an unknown related view. This is not fun or maintainable. It can add hours to your development time or cause serious bugs in the form of bad user experience or even infinite update loops. This is where Flux is beneficial, especially when you have more than a few models and views.

Flux, at the most basic level, looks like Figure 5-3, with an action, dispatch, store, and view layer.

9781484212462_Fig05-03.jpg

Figure 5-3. Basic Flux data flow

This is the basic structure of how data flows through a Flux application. The initial state of the data flow comes from an action. This action is then transferred to the dispatcher.

The dispatcher in a Flux application is like a traffic officer. This dispatcher will ensure that the data flowing through the application will not cause any of the cascading effects that you might see with a many model and view MVC setup. The dispatcher must also make sure that the actions are executed in the order in which they arrive so that race conditions are prevented.

The dispatcher the store takes over for each action. Once an action makes it to a store, actions are not allowed to enter into the store until the store has completed the processing of the current action. The views then respond to the store once the store has indicated that something in the data has changed.

The views themselves can contribute to this data flow by instantiating another action, which then passes through the dispatcher to the store and back to the view, as shown in Figure 5-4.

9781484212462_Fig05-04.jpg

Figure 5-4. Flux with a view creating its own action and passing that to the dispatcher

You are likely wondering if the view component of this data flow is where React fits into Flux. Well, this is precisely where React fits into the Flux model. You can think of the React components in your application as items that are rendered based on the data that is transferred from the store portion of the data model.

What about the actions that are created from the views themselves? How does React create an action to be sent to the dispatcher? This could simply be the result of a user interaction. For example, if I have a chat application and want to filter a friend list or something similar, React will create new actions as I interact with that portion of the component and those actions will pass to the dispatcher to initiate another Flux process, as shown in Figure 5-5.

9781484212462_Fig05-05.jpg

Figure 5-5. Full Flux architecture, including calls from data stores

Figure 5-5 shows the full lifecycle of a Flux architecture. This starts with some sort of data API, which then sends information or data to the action creators. The action creators, as the name suggests, create actions to pass to the dispatcher. The dispatcher then polices these actions and filters them to the store. The store processes the actions and pushes them to the view layer, which in this case is a collection of React components. These React components can then have user interactions that pass their events or activity to the action creators in order to continue the process. Next, you will see a more detailed breakdown of these Flux components.

The Basic Components of Flux

Flux is composed of four major components, or what can be considered at the very least to be core concepts. These are the dispatcher, stores, actions, and views, as you learned in the previous section. They are described in more detail in the following sections.

Dispatcher

The dispatcher is the epicenter of the data flow in your Flux applications. What this means is that it controls what flows into the stores of the Flux application. It does this because the stores create callbacks that are linked to the dispatcher, so the dispatcher serves as a housing place for those callbacks. Each store in the application creates a callback that registers it with the dispatcher. When an action creator sends a new action to the dispatcher, the dispatcher will ensure that all registered stores get that action because of the callback provided.

The ability for the dispatcher to actually dispatch the actions to the stores via callback is essential for larger-scale applications because the callbacks can be managed to the point where they execute in a specific order. Also, stores can explicitly wait for other stores to finish updating before they update themselves.

Stores

Stores contain the logic and state of a Flux application. You might think of these as essentially the Model portion of a traditional MVC application. The difference is that instead of representing a single data structure like a traditional model, the store in Flux can actually represent the state management of many objects. These objects represent a particular domain subset within your Flux application.

A store will register itself with a dispatcher and provide it with the callback, as was mentioned in the previous section. The callback that’s passed in will have a parameter that is the action, passed to it via the dispatcher. The callback will also contain a switch statement that is based on the type of action and allows for the proper delegation into the function, or methods, contained internally within the store. This is what allows the store to update state via the action provided by the dispatcher. The store must then broadcast an event dictating that the state has changed so that the views can fetch the new state and update the rendering of the application.

Actions

Actions are actually any form of data that has been dispatched to the stores. You will see later in this chapter a basic example of actions and action creators for a simple TODO application using the Flux architecture.

Views

The view layer is where React fits into this architecture. React, with its ability to render the virtual DOM and minimize complex DOM updates, is particularly useful when creating a Flux application. React is not just the view in itself. In fact, React at the highest level of the view hierarchy can become a sort of controller-view, which can control the user interface and render any particular subset of your application.

When a view or controller-view receives an event from the store layer, it will first make sure that it holds the freshest data by accessing the store’s getter methods. It will then use setState() or forceUpdate() in order to render() properly into the DOM. Once this happens, a controller-view’s render will then propagate to all the children that it governs.

A common paradigm for passing the state of an application to a controller-view and subsequently to its child views is to pass the entire state as a single object. This provides you two benefits. First, you can see the state that will reach all parts of the view hierarchy, thus allowing you to manage it as a whole, and second, it will reduce the amount of props that you need to pass and maintain, essentially making your application much easier to maintain.

How React and Flux Look Together

Now that you have a basic understanding of how Flux and React work together and how they are utilized, the remainder of this chapter will focus on a simple TODO application. Just as the introduction to React in the earlier chapters focused on TodoMVC.com, this chapter will examine the basic TodoMVC application utilizing Flux, before moving on to a more complex chat application in the following chapter.

The HTML is similar to what you have previously seen, where you will be building all of your JavaScript resources into a single bundle.js file. To follow along, you can clone the Flux repository at https://github.com/facebook/flux.git and navigate to the examples/flux-todomvc directory. You can then use the npm install and npm start commands and navigate your browser to the index.html file to view the example. What these commands do is utilize npm to install the dependencies for the Flux examples. This includes the actual Flux npm package, which, while not a framework, includes the dispatcher and other modules that allow the Flux architecture to work properly.

Image Note  The code shown in Listings 5-1 through 5-10 is licensed by Facebook under a BSD License.

The main bootstrap file that the bundle.js file is based on is the app.js file shown in Listing 5-2. This file requires React and includes a reference to the TodoApp.react module, which is the main component for the TODO application.

The TodoApp.react.js module, as shown in Listing 5-3, requires the Footer, Header, and MainSection components of this Flux module. In addition, you see the introduction of the stores/TodoStore module.

The MainSection component follows in Listing 5-4, and is just as the title suggests—the component that controls the main portion of the TODO application. Note that it includes the first reference to the TodoActions module as well, which you will see later in this example. Aside from that, this is a React component that you would expect to see; it renders the main section, handles some React props, and inserts the TodoItems, just like the non-Flux—based React TodoMVC application you saw in the earlier chapters.

The TodoItems component (Listing 5-5) is very similar to the non-Flux version of this application. Note that the events bound to the DOM, just as in the MainSection, are now linked to a TodoActions function (this is shown in bold text in the examples). This allows the actions to be tied to the Flux data flow and to propagate appropriately from the dispatcher, to the store, and then finally to the view. Similar bindings to TodoActions are found in the Header (Listing 5-7) and Footer (Listing 5-6) components as well.

Now that you have seen how the React components send events or actions to the TodoActions module, you can examine what the TodoActions module looks like in this example. It is simply an object with methods that tie to the AppDispatcher (Listing 5-8).

The AppDispatcher is a simple instance of the base Flux dispatcher, as you see in the previous example. You see that the TodoActions functions, shown in Listing 5-9, each have something to do with the AppDispatcher. They call the dispatch function, which holds an object that describes what is being dispatched from the dispatcher AppDispatcher.dispatch( /* object describing dispatch */ ); You can see that the object that’s dispatched varies based on which action is called. This means that the create function will produce a dispatch with an object that contains the TodoConstants.TODO_CREATE actionType passing the text of the TodoItem.

Finally, in Listing 5-10, you encounter the TodoStore.js file, which is the intermediary between the actions, dispatcher, and views. What you see is that each of the events that are processed in the functions in this module are also called from within the callback registry. This registry, which is emboldened in the example that follows, powers all of the delegation between the dispatcher and the views. Each of the functions will do the work that is needed to update the values of the TODOs, after which the method TodoStore.emitChange() is called. This method will tell the React views that it is time to reconcile the views and update the DOM accordingly.

Summary

This chapter was a departure from pure React in a way that begins to show you how the React ecosystem works as a whole. Starting with describing how the Flux architecture provides a meaningful and useful mechanism to structure a React application so that it is not only maintainable, but efficiently scalable, you saw how to route your data flow in a single direction to provide the best in class development practices for your React applications. You then took a quick look at the Facebook version of a simple Flux TodoMVC application that showcases how you can begin to structure your React applications in the Flux architected way.

In the following chapter, the last in this introduction to React book, you will dissect a fully functioning Chat application built with React and Flux so that you can get a full understanding of how a complex application can be created in a maintainable and scalable way.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.99.82