37

I know that ReactJS isn't considered MVC, because the creators themselves have said so. But, recently, I was asked WHY React it isn't considered MVC even though it fits the MVC pattern. React renders a view, and when the someone using the client makes changes, React will take into account the change, update a state if needed (and isn't state just the model?), then return the updated view (just like a controller would). I have a very basic understanding of the strict definitions of MVC architecture, and am extremely confused by why React isn't MVC now.

albert
  • 1,158
  • 3
  • 15
  • 35
  • I think the person who asked you that question was either baiting you or doesn't understand React. – Robert Harvey Dec 11 '18 at 17:37
  • 1
    Either way, they have me confused about React and MVC too now. – albert Dec 11 '18 at 17:38
  • 4
    In my experience, MVC is an overloaded term. You can call React MVC if you want; you could also call [Backbone](http://backbonejs.org/) MVC, but you're going to have to think differently depending on which you use, so the MVC label doesn't provide much. – SimpleJ Dec 11 '18 at 17:40
  • There are several articles on the Internet about this. You can read them and make up your own mind. – Robert Harvey Dec 11 '18 at 17:47
  • So you could technically say that React does fit the MVC framework, and that would be an acceptable answer? – albert Dec 11 '18 at 18:04
  • Acceptable to whom? – Robert Harvey Dec 11 '18 at 18:05
  • I'm not a React expert, but the articles that I looked up in the few minutes I had researching your question suggest that React is simply **V**, not **MVC**, and that you have to add other components to it to simulate MVC. – Robert Harvey Dec 11 '18 at 18:06
  • 2
    So then the lifecycle methods in React wouldn't be considered controllers, and state isn't a model? What are the demarking factors for the models and controllers? Sorry, I'm just actually seeking an explanation – albert Dec 11 '18 at 18:09
  • Why doesn't the answer posted below suffice? – Robert Harvey Dec 11 '18 at 18:11
  • 4
    It explained the difference between MVC and Flux, and stated that React is the View, but was still vague on why React Component methods and state isn't considered the M and C part of MVC – albert Dec 11 '18 at 19:01

3 Answers3

29

React is neither MVC or notMVC. It's a library to render the View (with a lots of cool stuff, but still). You can use either MVC patterns, or Flux/Redux, or whatever.

The difference between MVC and Flux is that latest implements unidirectional data flow. So your data can move only one direction. Action -> Middleware -> Store -> View. MVC is bidirectional; you can change Model from View and from Controller.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
Dima Vishnyakov
  • 1,361
  • 10
  • 21
  • 2
    > "MVC is bidirectional; you can change Model from View and from Controller." I can't see any info that indicates that MVC allows changing the Model directly from the View. Quite the contrary. MVC enforces changes/actions to go through the Controller: https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller The View simply: "renders presentation of the model". – Magne Jun 01 '22 at 17:57
  • I'm talking about real life use cases. Have seen many in my experience. Though you may be correct from an academical point of view, but such a distinction is not possible in the real world of front end. That's why we have Redux. – Dima Vishnyakov Jun 02 '22 at 14:22
  • 1
    Yeah, I think the confusion stems from people having typically misconcieved MVC and implemented it with (oh-so-convenient) two-way data-binding. Then, [Facebook blamed MVC](https://www.infoq.com/news/2014/05/facebook-mvc-flux/) for the resulting complexity, instead of the two-way data-binding implementation which was really the problem (and which Flux/Redux really was the solution to). I've explained more in the second to last paragrah in [my answer](https://stackoverflow.com/a/65969849/380607), FWIW. – Magne Jun 03 '22 at 13:51
28

React is not considered to be MVC

React isn't considered MVC because it doesn't map very well with how MVC has been conceived and used on the back-end.

React is a rendering library and ideally just takes care of the View layer. It doesn't have a centralized orchestrator/router nor entirely separate (REST-style) controllers as MVC architectures on the back-end typically came to have.

Since Facebook inaccurately contrasted Flux with MVC

In delineating a shift with existing approaches, the Flux architecture was contrasted with MVC (read Faceboook's MVC Does Not Scale, Use Flux Instead).

But Flux is not in direct opposition to MVC per se, but in opposition to mutability and two-way data-binding, something which MVC does not specify (it even says Views simply "renders presentations of the model").

You could argue that the Flux architecture simply reframes MVC, renaming Model-View-Controller to Store-View-Dispatcher... The important difference is not the architectural entities per se, nor their names, but how you restrain them:

Flux disallows the two-way data-binding that people often allowed when using MVC. This restriction makes debugging easier (just trace up the React tree, instead of back-forth between components, and in the case of mutability: you'd have to trace also into each preceding component that used the value), and avoids performance issues like cascading state changes (bouncing back-forth between Models and Views, with subtle timing issues) that people experienced with two-way (aka. 2-way, bidirectional) data binding. (Even though two-way data-binding actually can be made safe, as Svelte does.)

Stateless MVC also didn't fit on the client-side

The popular implementation of MVC on the server side had come to be synonumous with statelessness, since web servers are generally stateless. But as Ryan Carniato from SolidJS points out, on the evolution of client side MVC frameworks:

«Basically, the stateless MVC architecture was the wrong one for the client.«

Since rich clients (SPA's) typically need to be stateful. I.e. rich clients need to preserve user state, and quickly handle user interactions, without necessarily requiring a round-trip to the server.

But React is MVC, in some sense

That said, you could say that React actually is MVC in some sense (closer to the original meaning of MVC).

React is slicing the MVC vertically (by concern), instead of horizontally (by technology) which was what people had come to do with the MVC pattern. See, MVC had become a layered architecture with the Views as a thin layer on top. (Although not originally meant as such [1]).

Thus, you could say Components in React started out as small vertically-sliced encapsulated MVC's: containing both state/useState (model), rendering (view), and control-flow logic (a localised mini-controller, if you will).

Currently, Components (in front-end libraries like React and SolidJS) mix rendering with rendering logic. Components have come to range from entirely View-oriented, to entirely Control-oriented. This can cause conceptual confusion.

But most components are somewhere in between; having a bit of both rendering output and control-flow-logic.

Components are ViewControllers, typically

So currently, React Components have become more of a vertically sliced ViewController, where the Model bit is contained somewhere else. E.g. in state handling libraries like the centralised Redux, or in separate/orthogonal Recoil stores. Or merely pseudo-contained in the Component with hooks like useState (whereas in reality contained by React itself).

So, Components can currently be seen as ViewControllers.

It's interesting to see the similarity of React Components with iOS' UIViewControllers [2]. Maybe this mental model from native iOS development influenced the creation of Components, considering Facebook with the React + React Native combo intended to have the same framework and mental model for working with pure Native and the Web.

'A View Controller (VC) manages views and helps in making the application’s UI. It coordinates with model objects and other controller objects. It is known for playing the role for both view objects and controller objects. Each VC displays its own views for the app content.' - iOS ViewController lifecycle

If you need further convincing, just read Apple's documentation of ViewControllers in Swift, and imagine they are talking about a React Component. There is virtually no resistance (aka. cognitive dissonance).

Components as Views, Hooks as Controllers

These days, with a lot of component logic extracted into Hooks, ryanflorence and swizecteller have noted that you could see:

Components more as mere Views, and Hooks as Controllers.

In the Remix SSR framework for React, victorsavkin has noted that:

"the loader+action combo is similar to the Controller in MVC. And the React component is basically the View."

Notes:

[1] - It's interesting to note that front-end programming (React) is still wrestling with implementing MVC as it was originally conceived by Trygve Reenskaug back in 1979, who already implemented it with Smalltalk.. It was implemented as slicing up the interface/screen into a myriad of tiny atoms/components which each follow a MVC pattern: See "Every little widget on the screen had its own Model, Controller and View." at MVC is not an Architecture. Although this approach has some drawbacks, especially related to syncing state changes, as noted at the section starting with "Sometimes MVC is applied at the individual widget level ..." in this excellent and visual MVC explainer article. (See what an MVC-widget could look like with React+XState)

In React however, syncing state was/is handled through 'prop drilling' (which becomes its own problem, solved by or centralized state libraries like Redux) combined with the one-way data flow of the Flux architecture (introduced by Facebook and often used with React, such as with Redux). See previous section.

[2] - It should be noted that the iOS ViewController - just as a Controller in an MVC pattern on the backend - might have more wide-reaching concerns (like cross-component-communication, less encapsulation) than a controller in the sense that a React Component is a ViewController. Since React Components are a part of the JSX/DOM hierarchy and Flux architecture of React. There are probably a few different definitions about what a "Controller" actually means. But for my intents and purposes I treat it as a center for control-flow logic (be it used for simply view rendering, or, as in the backend case, also for routing and model orchestration).

Magne
  • 16,401
  • 10
  • 68
  • 88
  • See also further discussion, most notably: "Simple React apps might be just 'VVM' or 'VC'" and 'Add some complexity, and you could call it 'MVVM'/'MVC'" by Tadas Antanavicius over at: https://stackoverflow.com/questions/51506440/mvvm-architectural-pattern-for-a-reactjs-application – Magne Jun 01 '22 at 18:12
  • 1
    What you essentially means is React is sort of MVC, we can consider it as slicing mvc vertically by that we mean each stateful component in itself can be considered as a MVC. State can be considered as Model, rendering logic (JSX etc) is View and event handler that updates the state (Model) are sort of mini controller. Data flow is unidirectional because view dispatches event, event handler changes state (model) and then view gets updated due to updated model just like how MVC work. One can also use Redux for state and simply use React as View layer. Is my understanding correct? – Suraj Jain Aug 07 '22 at 07:18
  • @SurajJain yes! – Magne Aug 07 '22 at 17:35
  • Is there any good source to read about all this? – Suraj Jain Aug 09 '22 at 03:13
  • @SurajJain I haven't found any, except for the ones I linked in this answer. That's why I wrote the answer (and improved upon it over some time). – Magne Aug 09 '22 at 14:07
7

I felt the accepted answer is a bit incomplete, so just wanted to add the three main points (when flux/redux is used to illustrate the answer).

From here: https://medium.com/createdd-notes/understanding-mvc-architecture-with-react-6cd38e91fefd

  • The flow of processing is unidirectional instead of bidirectional

  • stores are able to store any application related state, whereas the model in MVC was designed to store single objects

  • the initiating point Dispatcher makes debugging much easier

JackDev
  • 4,891
  • 1
  • 39
  • 48