As the single page requirements of an application become more and more complex, the management of application state becomes more and more chaotic. Application state includes not only data retrieved from the server, but also data created locally and reflecting the state of the local UI, and Redux is designed to address this complex problem.

To summarize what Redux is: Redux is a predictable state container for JavaScript applications.

Short as it is, it has several implications:

  • Predictable: Since Redux adopted the concepts of reducer and pure function, each new state will be built with the old one by a new one, which can be used for time-travel debugging. Therefore, all state changes are “predictable”.
  • State Container: State is a single store in a tree structure of a single object. Store is a collection of states in the app domain.
  • JavaScript applications: Redux isn’t just designed for React. It’s a standalone library that can be used in a variety of JavaScript applications.

Some people might think that Redux started out as a Facebook project, but it’s not. It’s primarily a project started by Dan Abramov, who recently joined Facebook’s React core group. React Hot Loader and React DnD are probably better known than the Redux project at the time. Shortly after Facebook published Flux architecture, a number of similar libraries/frameworks for Flux architecture, Whether it is the enhanced version, the evolution version, the revision and so on very much. Redux’s first large-scale demonstration was in the React-Europe seminar in 2015, with the video Live React: Hot Reloading with Time Travel. There’s a simple explanation in the video where Redux uses the concept of “Flux + Elm”.

Of course, in addition to Flux and Elm, there are other major concepts and design methods like those in RxJS. Redux integrates various technologies, and extends some different design methods in addition to the more ideal application of Flux to solve the problems. But for beginners, it is not easy to learn, the network often see beginners complain that Redux is hard enough to learn, this is not entirely the problem of Redux, basically speaking, Flux architecture is not easy to understand, Redux also simplifies the process and development mode of Flux.

So we need to understand what Redux is. We can understand it from the two bases of Flux and Elm. The following are some basic concepts.

Flux

Either Flux or any of the other library of Reflux functions based on the Flux architecture (Alt, Reflux, Redux…) It’s all about solving the same problem that will become obvious when React applications scale. Simply put: The state of the App domain — app State.

Every application needs App State, whether in an application that requires user login, to have a global record of user login status, or in the application of different operation interfaces (components) or data communication on various functions, it is needed. If you already have some programming language or application development experience, you should know that this is something that the Model part of the MVC design pattern should do.

Why does React have this problem? This is mainly due to the design of the React component. React was designed to be a library similar to MVC’s Views. It can actually do a lot more than MVC’s Views, but it’s not a complete application development framework at heart. There’s no extra architecture in there that can do things like Model or Controller. For a small component or application, the application’s data is contained within it, in the View.

If you’ve learned the basics of React, you’ll know that components in React can’t change the state value directly. Instead, you need to change the setState method. This is largely because it’s designed for the Virtual DOM. In addition, in the hierarchical tree structure of components, the relation between parent component (owner) and child component (owner), the parent component can only pass the property value as props, and the child component cannot change its own props. This is why when learning React at the beginning, You’ll see that in most cases only the topmost component has state and is responsible for rerendering when the data changes, while subcomponents are usually only responsible for rendering the data.

The method declaration in the parent component is passed to the child component by props. Then, when the child component triggers an event, the method of the parent component is called. This allows the child component to communicate with the parent component and indirectly change the state in the parent component. This approach is not intuitive, however, and requires a well-regulated approach to both sides. This can work in simple applications, but it is not useful when there are complex nested hierarchies of components, such as many hierarchies or when sub-components in different tree structures communicate with each other.

In the case of a complex tree of components, the only way to do this is to consolidate the data of the entire application and then isolate it, that is, the data portion of the entire application domain. It also needs to be independent of all changes to the data. Together, the two are called “application domain state.” To distinguish the states in the component, the collection of persistent data as an application domain is called a store.

A store is not just an application’s collection of data, it also contains all the ways in which that data can be changed.

The role of store is not only the state in the component, nor is it just a simple record of data. It is possible that every different library of functions extended by Flux today has a different definition and design for store. In store of Flux architecture, it contains functions/methods that change data. Flux calls these functions/methods “Store Queries” and positions its role as a Model similar to traditional MVC. However, the biggest obvious difference from traditional Model is that Stores refresh themselves only in an “indirect” way through actions.

The design of Store can solve the problem of application state storage and change, but it can not solve the whole problem completely, it is only a beginning. The hardest part is how to perform store change queries when the action is triggered, change the rendering data and render the entire application. Flux uses unidirectional Data Flow to design the operation of the whole Data Flow, that is, the Flow direction of the whole Data is consistent. From the action interface component presented on a web page, to the event that triggers it, to the sender, to the Store, and to the rerendering of the entire application, all move in a single direction.

Therefore, one-way data flow is the core design of the Flux architecture. Here is Flux’s simple flow diagram:

The central design of this data flow is an AppDispatcher, which you can think of as a sending center through which actions from wherever the component is coming from will be sent. Each store registers itself with AppDispatcher, providing a callback that the AppDispatcher uses to notify the store when an action occurs.

Since each Action is just a simple object containing actionType and data (usually called payload), we need Action Creator, which is a set of helper functions. In addition to creating actions, actions are also passed to the Dispatcher by calling the Dispatch method in the Dispatcher.

The purpose of the Dispatcher is to broadcast the received actionType and payload to all registered callbacks. It is not an original design, it is similar to pub-SUB (publish-subscribe) system in design pattern, Dispatcher is similar to Eventbus concept. The Design of the Dispatcher class is simple. There are two core methods that are functions that are related to each other:

  • Dispatch sends payload(equivalent to action) to all registered callbacks. This is how a component sends an action when it fires an event.
  • Register registers callbacks to be called when all payloads (equivalent to actions) are sent. These callbacks are store Queries that will be used to change stores.

At the end of the stream, store triggers setState for the topmost component and then rerenders the entire React. The method proposed by Flux is a self-customized event monitoring method, which expands store with EventEmitter. Prototype object to enable store to monitor events, and then adds monitoring events when changes occur in the life cycle of the uppermost component. This is because JavaScript interfaces such as Event and CustomEvent, as well as methods such as addListener and Dispatch, can only be implemented on web DOM elements with Event interfaces. There is no way to use it on JavaScript objects alone, but additional libraries are needed to do so, which is one of the main reasons to use libraries like EventEmitter.

However, you may be wondering why not just change the store directly, but take the big detour and refresh yourself through Action “indirectly”?

I think one of the reasons is to standardize the specification of actions, which means that all components in the application have to trigger events based on those actions, and the callbacks registered in the sender have to be written as actions that handle the same specification. Action is mainly composed of type and payload. The Flux Standard Action is proposed to standardize the format of Action. With a unified format of Action objects, When refreshing data, all refresh methods are consistent, so that Flux can complete a cycle of data flow operation and then the next. Like transport protocols, there are standards for how data is formatted and how it works, and it can’t just be transferred. There are other reasons, like avoiding Event Chains.

The entire process can be represented as follows:

Action Creator calls Dispatcher. Dispatch (Action) - Dispatcher calls registered callback (callback) - call Store Queries -> Trigger Store change event -> Rerender the entire applicationCopy the code

In summary, Flux uses a one-way data flow design architecture to address the React application domain state problem. The implementation of Flux is not easy, and many details of the implementation and development steps are unclear, so the implementation part of Flux is not discussed here. After the release of Flux (around the middle of 2014), many function libraries and frameworks have emerged, all of which are based on the basic design concepts of Flux and are mainly aimed at improving, simplifying or automating the implementation steps. Redux is one of them. After a period of time, Redux, which is popular and used by more people, has a lot of design concepts from Flux. It is definitely helpful to understand the basic design concepts of Flux and learn Redux.

Elm

You may have heard of the development style of functional programming (FP). What is FP? To illustrate this, the following sentence is taken from the tutorial document: Functional development is a way of writing software applications using only “pure functions” and “immutable values”.

FP is a very popular program development style nowadays. There have been some pure functional program development languages such as Haskell and OCaml for a long time. Elm is also a pure functional program development language, which is a very young language. Eventually compiled into JavaScript to run on web pages, it is much different from the JavaScript language design, for example:

  • Elm is strongly (static) data typed, and its data types are diverse;
  • Elm is a pure FP language;
  • Elm-architecture is an application framework included in Elm. It is a one-way data flow Architecture.

React and Flux have many designs, which are applied to FP, which are quite similar to part of Elm. And Redux uses more Elm designs, especially elm-Architecture, for example:

  • Immutability: All values are immutable in Elm. The pure function in Redux is similar to the Reducer design, and the React design also has such concepts
  • Time Traveling Debugger: Redux learned from this design on Elm

Description: The author of Redux uses THE architecture of FP(Functional program development) and Elm to improve or simplify the original Flux architecture.

Story features

Redux is currently the most popular and used library for Flux architecture classes, and while Redux can be used with other libraries, it was basically built specifically for React applications. If you really want to learn React and use it to develop a moderately large application, learning Redux is the way to go. There are also other Flux architecture libraries to choose from, and the solutions and styles that might be used by different libraries can vary greatly. Redux’s development community is by far the largest and most active, and it’s not likely that other libraries will be easier to learn and use. After all, with more people, the problems you will encounter will probably have been encountered before, and they can find solutions. This is the bonus of the open source ecosystem.

Redux is popular for a number of reasons. Here are some of the benefits of Redux:

1. React works well with FP(functional programming)

Different from Flux architecture, Redux adopts a nearly pure FP(functional program development) solution to simplify the processing of data flows in Flux. Redux also works well with React component rendering, proving that it has found a relatively ideal solution to work closely with React applications. FP(Functional program development) is a hot topic in JavaScript right now, and Redux is attracting a lot of attention from developers.

2. Time travel debugging/hot reload

Redux comes with time travel debugging tools and hot reloading tools to improve the development experience, which are very attractive to developers. It also means that data changes in Redux applications are easier to test and debug. This is not seen in any other Flux architecture class function library or framework.

3, more simplified code, more possible extension applications

Redux starts with 99 lines of code, which is probably less API than the original Flux architecture, but less code doesn’t necessarily mean simpler concepts. FP’s writing style is mostly for shorter code, which requires a lot of skill, depth of concept, and a lot of foundation. Redux is easy to use for server-side rendering from the start, and it’s not limited to React applications, which has attracted more developers to use it.

4, more documents to develop a good ecosphere

The Redux author has written a lot of documents and tutorials from the beginning, making it easier for many developers to learn the techniques of Redux. The Redux author is also a regular on the technical discussion boards, where he can often be seen answering questions. The Redux project is also very active, with a large number of participants discussing and solving problems, and solving major performance/bug problems very quickly.