How React and Redux brought back MVC and everyone loved it
Reading time: 3 minutes
Are we still talking about MVC? Isn't it dead already, with UML and waterfall? We want to soar through the cloud, create lambdas, use modern stacks, integrate with top-of-the-line libraries, the latest and the greatest — not something from a dust-covered book written a long time ago, in a galaxy far, far away. I hear you, young Padawan, but give me a few minutes of your time, and I'll explain how those two intersect, and how you can sit on the shoulders of giants.
Let's stroll down memory lane with a diagram of the MVC pattern:
Some argued that MVC was not good because of its bidirectional data flow. But, as you can see in the diagram, the flow is only one way.
Let's start from the model: where we can load the data. From there, it updates the view to reflect that data, what we also call a state. The users visualize that, acts on the page, which in turn calls the controller. Then updates the model, which triggers an update in the view.
Now, let's bring this closer to what we use nowadays with some name changes in the diagram, and see what it looks like:
Doesn't that reflect a React/Redux application? With these similarities, let's look into what Trygve Reenskaug (the creator of MVC) meant by his pattern and how it compares to React/Redux:
The Model (Store) would keep a small portion of the business logic, while the Controller (Reducer) is responsible for handling the input from devices (mouse, keyboard, etc) and converting those input signals into method calls against the Model. The View would observe these changes, and reflect the UI accordingly. In the React/Redux world, the Reducer (Controller) has more responsibility, handling the Store (Model) directly, but the data flow remains the same.
Breaking down the MVC pattern
In essence, the purpose of the MVC pattern is to organize the data and its interactions with the user. We can link it to the Separation of Concerns (SoC) design principle, which is a common issue developers need to deal with.
The idea to bring the MVC principles to a React/Redux app is to ensure that the complexity of the business is handled in such a way that, as the application grows, each part of the code deals only with a small portion of it, and those responsibilities don't overlap or cross boundaries.
Following the MVC design, a React component will only be responsible for presenting the state from the Store, and not keep any `React.useState` inside it, so the data for that component will only come from a prop or read inside the component, by accessing the store. Either way, the major responsibility of the component will be to receive the data and render it. That's it. No side effects, no fuss.
On the other hand, to handle the changes in the data, all logic will be in the Reducer (Controller). That way, if the component is not updating the Store correctly, there is a single point of failure. Not only is there no need to check the component, but because the change is due to an action, it is easy to track the Reducer responsible for the problem. This can also be linked to Separation of Concerns, as the Store becomes the interface between the components.
As you can see, applying the MVC pattern to a React/Redux application is mostly about separating the concerns to where they make the most sense, and handling the business complexity where it will be easier to maintain.
The bottom line: Redux vs. MVC
Redux adds immutability to MVC, and with it a history of the changes in the State. This allows the developers to see how these changes affected the presentation, and track in which step the Reducer caused a problem (since the logic to handle the data is isolated there), using the rewind functionality for even more specificity. Also, since the state stored in Redux is immutable, there is no need to observe the state of the data to trigger the changes in the View. Since the Reducer is responsible for the update, it can also track which portion of the State has changed, and trigger the view accordingly. Furthermore, immutability removes any side effects that could exist by changing the data, like having to deal with synchronization and consistency.
In conclusion, having a React/Redux application starts you on the MVC path even without you knowing it. Following it consciously will allow your code to evolve in a more organized way—and help you keep your sanity as the project grows.