MVC was originally designed as a pattern for desktop UIs. It has a single controller and a single model, not the MVC style that Rails popularized with one controller class and one model class for every kind of data. In classic MVC, Views query the Model for relevant data. The Controller handles user actions and uses that to update the Model, then asks the View to redraw (preferably in some smart efficient manner). This is unidirectional data flow pur sang and it comes from 1988. How is React+Redux any different from this?
I agree with the author that components are the true innovation of React, because it encourages reusable building blocks by default. Contrast with classic desktop and mobile UI toolkits which, while often also using or encouraging MVC, do not require the developer to not subdivide their own codebase into reusable widgets. Instead, they allow composing an entire screen (window, page, form, whatever) from the built-in widgets. Making a reusable widget is possible but extra work and therefore not done. In React, it's the only way to go.
This is awesome about React, but it has nothing to do with data flow architecture, which is what MVC is.
The mistake webdevelopers made for years was trying to shoehorn DHH's backend remix of MVC into the frontend, throwing away decades of UI building architecture knowledge. I'm happy the Facebook people rediscovered MVC and I'm even happy they gave it a new name (Flux) because MVC frankly has gotten way too many definitions.
But saying that Flux/Redux killed MVC is like saying Clojure killed Lisp.
If anyone cares, by the way, actually having a Controller has done wonders for our code at TalkJS. Our View is purely React components, all of which only deal with presentation logic and local interaction logic. The components query the store (Model) for data, like in any Flux/Redux setup and like MVC has encouraged for decades.
Then, user actions are handled in the Controller. In our case it's just a bag of functions. The Controller fetches and pushes data from/to the backend, and sends appropriate actions to the store. This allows us to keep all the backend data fetching/manipulation logic out of the View, which keeps the View clearly focused on the UI and the UX, and nothing else.
Our controller does not have read access to the store: any data the controller functions need to do their work is passed in from the view (which has the data anyway because it used it to query the store appropriately).
This works great, it's total unidirectional data flow, it's also pure classic MVC, and I haven't seen anyone describe it elsewhere. We came up with it 2 years ago when React was pretty new and I had little else than MVC to be inspired by.
If you have data molding code all over your views (and a little bit elsewhere too, for good measure), consider a controller.
Correct me if I'm wrong but I think what you have is described as an "action dispatcher" these days.
For what it's worth, I think, we can define the whole Flux architecture in somewhat-skewed MVC terms. Not trying to downplay the usefulness of Flux here but if I'm not all wrong, it would've helped many people if we kept at least some of the terms from MVC or MVVM.
Ah cool, thanks. Does the action dispatcher also interact with the backend? My understanding was that it just created little action objects and little more. Our controller is decidedly more heavy-weight. I'm not saying it's the best possible way to go but it's been working well for us so far :-)
In redux terms, your controller would be the bundle of "action creators". If you use vanilla redux, those would conduct all your "logic", including communicating with the backend. This has some pros and cons, so there are extensions("middlewares") to redux which iterate on the concept - redux-thunk, redux-saga, etc.
Since redux largely defines the design of the "Model" part and React largely defines the design of the "View" part, most of the variation when using React and redux is how to design your "Controller".
It is indeed very close to how you would model redux apps. Interesting that you mention that your controllers don't have read access to store(s). That is actually very common with redux-thunk or redux-saga.
AFAIK it doesn't, but I'm just learning. My understanding is the standard way of doing things work if you are creating the most boring CRUD apps but you need to "bend the rules" a bit to make it work for your use case very often - as long as you keep it newcomer-friendly.
> MVC was originally designed as a pattern for desktop UIs. It has a single controller and a single model
Not quite. Let me quote from "A cookbook for using the model-view controller user interface paradigm in Smalltalk-80" by Glenn E. Krasner and Stephen T. Pope, 1988, which according to Wikipedia defined the term MVC originally:
> In the scheme described above, views and controllers have exactly one model, but a model can
have one or several views and controllers associated with it.
All that said, they mean that you should use separate controller-view pairs for entirely different pieces of the application. A nice example would be MS Word's document editor (1 view with 1 controller) and MS Word's Print Preview view (same model, but a separate view and a separate controller).
What I was getting at is that in backend-MVC (and backbonejs-MVC), you usually build a view, a controller and a model for each domain entity (i.e. for each database table). This is fundamentally different from what Krasner and Pope describe, and it probably won't work well for the kinds of dynamism and interactivity most single-page apps are single-page apps for. I believe this is the flavor of MVC the author is talking about.
In our case at TalkJS, we don't have anything like a print preview - essentially our entire application is a pretty unified piece of UI (much like MS Word's document editor which, while complex, is pretty much inseparable), so we have only one controller and one root view. I made the thinking mistake that most UIs only have one root view, and of course that's not true. So thanks for that.
The Model, View, Controller terms were originally defined by Trygve Reenskaug in 1978, based on his Smalltalk involvement, and formalised as Models-Views-Controllers in a 1979 paper.
% MVC was originally designed as a pattern for desktop UIs.
i still remember the MFC class library for Visual C++. it needed MVC for MDI applications where you have multiple document windows within one application window. Later MDI (and MFC) went out of fashion.
Later MS had ATL and WTL and here they had no MVC. i think not all C++ GUI class libraries were model/view/container, borland's wasn't
Also java class libraries for GUI did not force MVC. Awt and Swing don't do that.
Therefore MVC is not the only paradigm used in GUI frameworks.
Last I checked, Borland's widget library (their "Visual Component Library", or VCL) was, like React, View-only. The idea was that the view is the hard part and you, the coder, can choose how to structure the rest of your application yourself.
So sure you can put all data management right inside your Delphi form, and plenty of coders did this. You can do that with React too. But larger applications often chose to go with MVC, where the appropriate fields inside the VCL components were updated triggered by changes in the model.
It's nearly entirely the same model. The view classes (Delphi components, forms, etc) can render (by setting attributes on widgets) and have event handlers (eg onButtonClick) which in turn invoke the Controller, which makes appropriate data changes in the model.
Nothing in Delphi enforces this, but it matches really well. Thne only big thing they missed was something akin to a Virtual DOM and shouldComponentUpdate, making figuring out which fields to update when cumbersome. But there's been plenty older solutions to this problem (such as damage/repair).
It's probably evolved a bit, but when Delphi had big momentum most developers used data-bound components that updated directly from DB view queries and whatnot.
There were complex components that did transformations on the data for reporting or complex grid displays, etc, but generally you didn't see an abstract formal model behind forms/views. If you did model outside the DB, you did it in such a way that the model looked like a database table or query (subclassing abstract DB proxy components the VCL gave you) and used components directly bound to that.
So, I guess in MVC terms, what you had was a form implementing View logic with components directly working from DB or DB-like data, and controller code behind the form doing event-driven manipulation. The controller code could hook data events too, and in that way reacted to "model" changes as well, but the "model" was actually hidden in DB bindings and components. For any model business logic more complex than you could handle this way, middleware was usually pushed.
This may have progressed since the early 2000s when I lost track of Delphi, but the idea of directly-bound display components was typical of the dominant DB-driven 4GLs of the time, including Powerbuilder and VB.
The absence of standard widgets makes React awesome?
People compose an entire screen from built-in widgets because usable widgets and layout algorithms make this possible. If you are trying to build more complex screens, people in "classic desktop and mobile UI toolkits" also build own widgets.
Projects like Material-UI are finally dragging frontend development into the 1990s of "classic desktop UI toolkits", only the layout functionality is still sorely missing.
I agree to almost every point, but note that in the MVC definition, each of the M, V and C are components, not classes. A component may be composed of several classes. So there's nothing inherently wrong with Rails' approach.
I just think that as opposed to the original idea, people started to stuff way too much into their controllers, which is what makes things messy. I agree that Flux helps enforce the way it was supposed to be.
On the contrary, I find that people stuff too much on the model because of rails. I've found that I much prefer very simple models to describe very fine grained parts of the data and use the controller for much of the tying of things together. You kinda of treat models as 'data components' if you will, mixing and matching them where needed in the view
That's the "Massive ViewController" anti-pattern (or just massive controller, if you're not in Apple land).
Classic MVC is really MVc, with controllers only handling a small set of interactions that are not directly between the Model and View, for example dialog boxes and such.
One problem with a "Big-C" approach to MVC is that whereas models and views are at least potentially reusable, the controllers are dependent on both M and V, and thus both proliferate and are not reusable.
Everything right now is just MVC-like. Yes you have some unidirectional PUB/SUB here or some immutable data structure there.
So what ? In the end, you still have the separation between the data, the way you manipulate the data, the way you display the data and a canal of communication for those.
This is the essence of MVC, and what everybody is doing right now is just a variation of it.
You could say Redux is a more constrained subtype of the 'single data flow MVC' you describe, which in turn is a subtype of 'all definitions of MVC which have existed'. In Redux actions are serializable, which opens up a bunch of other possibilities. Not to say Redux invented that idea by any means (it's the FP principle of separating data and behavior, also the OO command pattern), but it's useful to have a name specific name when talking about a more specific combination of ideas/constraints, especially if those constraints make different things possible (undo/redo, replay, logging/analytics for free).
Firstly, I'm not sure it's an entirely accurate description to call Smalltalk-80 (where MVC was invented) a desktop UI given how unfamiliar it would be to users of MacOS or Windows.
Secondly, MVC was certainly not invented in 1988. It was a product of the work at Xerox PARC in the late 70s.
It's worth pointing out that Dan Ingalls and Alan Kay and other pioneering people involved in Smalltalk ended up 'repudiating' (to use a strong phrase maybe) MVC in later versions of Squeak (which is a direct descendant of the original Smalltalk-80 implementation) uses the "Morphic" GUI system which was built for Self at Sun in the 80s.
Morphic is a prototype oriented, direct manipulation system.
None of this has historically translated well to the web, where the HTTP request cycle and the nature of the DOM and JS execution model changes things significantly. MVC was never a good model for the web.
Note that React is enforcing functional programming principples. Stateles and immutable objects by default. Thats was not how it was done in 1988.. In react the views doest fetch new data... The whole view is regenerated when there is new data. In a functional style.
But i agree you could fit React in the MVC pattern. Only the view is purely functional.
I agree with the author that components are the true innovation of React, because it encourages reusable building blocks by default. Contrast with classic desktop and mobile UI toolkits which, while often also using or encouraging MVC, do not require the developer to not subdivide their own codebase into reusable widgets. Instead, they allow composing an entire screen (window, page, form, whatever) from the built-in widgets. Making a reusable widget is possible but extra work and therefore not done. In React, it's the only way to go.
This is awesome about React, but it has nothing to do with data flow architecture, which is what MVC is.
The mistake webdevelopers made for years was trying to shoehorn DHH's backend remix of MVC into the frontend, throwing away decades of UI building architecture knowledge. I'm happy the Facebook people rediscovered MVC and I'm even happy they gave it a new name (Flux) because MVC frankly has gotten way too many definitions.
But saying that Flux/Redux killed MVC is like saying Clojure killed Lisp.