Flux / Redux: Managing Application State in React
This is the final installment of four articles I am writing during my 15-week Software Development bootcamp at Flatiron School, in downtown NYC. For each article, I will focus on a topic that directly relates to my learning at the present moment. The metacognitive benefits to myself are obvious, and I hope they may be useful resources to my peers as well. My first article was about setting up my own custom Visual Studio Code color settings environment. My second article was about my first time using the Ruby on Rails Resource Generator, which creates an instant Full-Stack MVC (Model–View–Controller) Web Framework (CRUD not included). In my third article, I described various methods for styling HTML pages, including my latest discovery, CSS styling executed dynamically from within a JavaScript file.
In this article, I will provide a conceptual overview of React application state management using the Flux implementation library, Redux.
What is state?
In a React app, state is a JavaScript object. State is something only class components have, unlike functional components. It is owned by the component where it is declared. Its scope is limited to the current component. A component can initialize its state and update it whenever necessary. When the state is passed out of the current scope, i.e its component, we refer to it as props. The state of a parent component can, and often will, become the props of a child component.
Component State
The description above refers to component level state in React. Each component has its own state, and data is passed between components as props, generally wrapped with callback functions. This can work fine for less complex applications, but eventually this type of architecture can become cumbersome. A single user interaction can cause multiple changes to the DOM, and the internal logic for managing the state of numerous components may cause a parent level component to become complex and unwieldy.
Application State
Facebook, the creators of React, quickly recognized the need for application level state, a state object available to all of the components in an app. And thus, Flux was born.
Flux is a design pattern, like its predecessor at Facebook, Model-View-Controller (MVC).
Unlike MVC, Flux uses a strict uni-directional data flow model, mirroring, to some extent, the flow of data through the branches of the DOM node tree. The Flux design pattern is made up of four parts.
User interactions with the DOM view
trigger actions
that describe what happened to the dispatcher
, which, in turn, update the state in the store
. Changes to the store re-render the DOM continuously, as user interactions repeatedly trigger the behaviors described above.
Facebook has an open-source library for their implementation of Flux, but over time, numerous alternative libraries have been developed. Of these, Redux has become the most the popular, with an extensive development and support community.
Redux
Redux is written in only 99 lines of code. You can actually read it, and understand all of Redux. At its heart , Redux follows 3 key principles:
Single source of truth The state of your whole application is stored in an object tree within a single store.
State is read-onlyThe only way to change the state is to emit an action, an object describing what happened.
Changes are made with pure functionsTo specify how the state tree is transformed by actions, you write pure reducers.
Reduce everything
Instead of the dispatcher, Redux makes use of reducers. A reducer (also called a reducing function) is a function that accepts an accumulation and a value, and returns a new accumulation.
In Redux, the accumulated value is the state object, and the values being accumulated are actions. Reducers calculate a new state given the previous state and an action, following a core Flux concept:
(state, action) => state
Reducers must be pure functions, returning the exact same output for given inputs, with no side-effects. Understanding what the JavaScript function, Array.prototype.reduce()
, is doing, is crucial to being able to make use of Redux.
According to the Redux webpage glossary, reducers are the most important concept in Redux. React and Redux offer innovative new ways of creating and managing the flow of data in the DOM, and represent the future of web-based application development.