Yield.IO: Enter Redux
React and Redux go hand in hand for building modern web UIs in JavaScript. While they are related, they are orthogonal projects maintained by different teams. It is possible to use React without Redux or Redux without React or combine them using the binding library react-redux.
In simple terms, Redux is a library used to store and propagate data in an application. But React itself can maintain of the state of components and share state with other components by traversing through common parents via callbacks. React’s own state management creates a high degree of cohesion (in the classical OO sense of the word) and contributes to component reusability. Redux co-author, Dan Abramov, is on the record saying: You Might Not Need Redux.
I wrote Yield.IO primarily to learn React, and I explicitly avoided the complexity Redux for as long as possible, but over the last two days I started hacking Redux into Yield.IO. I’m using Redux to solve a specific problem which can’t easily be solved within React itself.
Internally Reacts keeps a virtual copy of the DOM and when changes are requested, they are diffed against the virtual DOM and the merged result is used to update the DOM in the browser. This process is known as reconciliation. For performance reasons (to ensure the algorithm runs with O(n) complexity) there are some limitations in the diff algorithm. When objects move around in the DOM, they can be destroyed and recreated. In most cases this only results in gratuitous component renders, but there is one more significant problem, the state of the component is lost and reinitialized. This post on StackOverflow describes the problem in more detail.
A secondary objective of Yield.IO is to eventually create generic analytical dashboards. This requires moving components around in the DOM when they are repositioned. I added a small feature this week which expanded the yield curve graph on the page by changing its position in the DOM. Rearranging the DOM caused the state of other components to be lost as they were destroyed and recreated.
After researching alternatives, I decided to save the state of individual components in a global Redux store. Effectively what happens is when an object is destroyed (because it is being moved in the DOM), its state remains in the store, and when it is recreated its previous state is restored from the global Redux store. Unfortunately if the component is truly destroyed, and not be simply moved in the DOM, the state could be leaked. This case needs to be explicitly handled and brings into the question the lifecycle of React components. While Redux solves one of my problems, it could create new ones as well.
In general, unless your application is very complicated, or you need to solve a specific problem like moving React components around in the DOM, then I would agree with Abramov. You might not need Redux. Personally I would delay the complexity of a state framework like Redux as long as possible and not always assume Redux comes with React.