Working With React and Flux

React and Flux

Recently, I’ve been learning a lot about React and Flux while developing a full-stack web application. React is a JavaScript library for building user interfaces, and revolves around the idea of writing your components in a very declarative way. It can be thought of as the “View” portion of the Model-View-Controller pattern. Flux is a pattern also developed by Facebook for building web interfaces - it utilizes the concept of unidirectional data flow, which complements React’s components quite well. In this post, we’ll take a quick look as to how React and Flux can work together to create the components of a dynamic, responsive web application. I’ve learned a lot of this through the excellent React Tutorial and applied my knowledge through following along a tutorial to create a full-stack app, the latter being the inspiration for this post.

React Overview

React is a powerful UI library developed at Facebook that uses an innovative diff algorithm to efficiently re-render components when data changes. With React, we don’t interact with the DOM directly - instead, React uses the concept of a Virtual DOM, which is just an abstract, lightweight representation of the actual DOM. This virtual DOM can then be manipulated and then saved to the real DOM tree. A major advantage of React is that this is done in an efficient way through the diffing algorithm used under the hood. The algorithm calculates the minimum number of elements it needs to update, and then efficiently re-renders the component by only applying these changes to the actual DOM. Calculating the diff between two trees (or more specifically, the “edit distance” between two trees) is a O(n^3) problem, but React uses heuristics based on a few practical use-case assumptions to bring it down to O(n). For more on that, check out the Docs.

React also has a few other notable features that make it pretty useful:

  • Server-side rendering of components: Since React doesn’t require the actual DOM tree as a dependency, you can render your components on the server as opposed to the client-side, and then just send the resulting HTML instead of having the client download and execute additional JavaScript. This could reduce perceived page load times.
  • Declarative style: components and elements allow you to write your component’s render() function in a declarative way.
  • Reusability and composability: React’s components naturaly lend themselves to be reusable if they are designed well (for example, ensuring each component has only a single responsibility), and are therefore easy to compose with other components to quickly build complex user interfaces.

Flux Overview

Flux is a pattern that complements React and the idea of unidirectional data flow. Its used internally at Facebook and is commonly paired with React. Its componsed of four components: Actions, Dispatcher, Store, and Controller Views, which manage the flow of data through an application and define what picks it up along the way. There’s many implementations of Flux, and the one I’ve been using is Alt.js.

React + Flux Example

Let’s create a simple React component, along with actions and a store for it. The store will be responsible for listening for actions and updating the state of our component accordingly. We’ll subscribe our React component to the store so that it knows about changes in the store, and can update its own state accordingly. Also, we’ll define a few actions that fetch data and notify the store about whether the data fetch was successful or not. Let’s get started with these actions first, which are placed into a file called MyComponentActions.js:

Here, we’ve defined three actions, one of which requests data from our backend, and two of which notify our store about the request’s success or failure. Note that we haven’t yet handled these two actions - that’ll be done when we define our handlers in the store. The store will also bind our actions to their handlers - sort of like a mapping from an action to the action handler. We’ll revisit this when we define our MyComponentStore class. The last line of the above code simply exports our actions so that they can be imported elsewhere.

Defining the Component Store

Now, we can move on to defining a store for our React component. The store will be responsible for handling the actions we’ve defined and updating the state accordingly, so that our component can listen for state changes. Let’s put this code into a file called MyComponentStore.js:

Here, bindActions is an Alt function that binds actions to their action handlers, with a specific naming convention. As an example, an action with name doAction will bind to onDoAction or just doAction (but not both). In this case, when our getMyMembersSuccess action occurs, the code in the handler onGetMyMembersSuccess will be executed and the members field of the state will be updated. With our actions and store defined, we’re ready to define our actual React component.

Creating the React Component

Our React component will fire off actions (such as, in our example, getting members from the backend) and listen to the store for state changes. When our component is initially rendered, it sets its initial state to the store’s state, and also subscribes a listener to the store to listen for changes so that its state can be updated accordingly (the OnChange function in the code below). Additionally, we can remove our store listener when the component is unmounted. Here’s some basic boilerplate code that could be used to design this component:

And that’s it! Hopefully, this was a good example to introduce how React and the Flux pattern work together to achieve unidirectional data flow, and how firing and handling actions update our component’s store. This full-stack tutorial is an excellent resource for learning more about React, Flux, and using Node to develop a full-stack app.

Sources

Written on September 20, 2016