Does React really violate Separation of Concern by putting HTML and JS in a single file?

View other answers to this thread
Start a personal dev blog on your domain for free and grow your readership.

3.4K+ developers have started their personal blogs on Hashnode in the last one month.

Write in Markdown · Publish articles on custom domain · Gain readership on day zero · Automatic GitHub backup and more

Rob Eisenberg's photo

Warning, this is going to be asked for it...

Answering this question well requires looking at React from a couple of different perspectives. It also requires understanding a bit of the 35+ year history of presentation patterns as well as an understanding of web technology's purposes and intents.

First, it's important to understand that Separated Presentation patterns emerged mostly in the context of creating component models on various platforms. For example, MVC originated in Smalltalk, Supervising Controller and Passive View have their origins in things like Java Swing and Windows Forms, and Presentation Model and Model-View-ViewModel have their origins in binding-based technologies like Xaml, Flash/Flex and modern Web frameworks. Components can be complex and engineers found that it was better to define distinct roles and responsibilities within a component. Take the classic MVC pattern. The roles and responsibilities of a Controller are different from those of a View. The role of the Model is different from either a Controller or a View. Yes, these all may be part of the same component, but they have different roles and responsibilities within that component. They are concerned with different aspects of the component's "life".

Note: I'm using SoC and SRP pretty interchangeably here. This isn't something you can/should always do in conversation. I'm taking this liberty because you will observe that, if you "zoom in" to a specific implementation detail of a system, SoC and SRP are actually talking about the same thing. That's not true if you "zoom out" to look at the bigger picture of a given system.

With that in mind, let's look at JSX first. What is the purpose of JSX? Does it have one or many? My understanding is that it's designed to serve the View role. To really understand this, you must see JSX as neither HTML nor JavaScript. You must see it as a unique View language. So, from the perspective of separated presentation, it seems to do a very good job, namely fulfilling only one role, that of the View.

That's the idea, but is that the reality? If you look out and see how developers are using JSX in practice, are they using it as a View language? My guess is that while JSX is intended to be a View language, it is probably most often being used as JavaScript with embedded HTML (this is what I've seen in most demos/presentations/samples/tutorials). This way of thinking of JSX can lead a developer to mix concerns. It's quite possible that the React component model may even encourage this since the same class controls state and renders it. I think the cleanest way to use React would probably be to treat the component class as a pure JavaScript ViewModel and to extract the JSX rendering logic into it's own class/object/function, which serves as the View for the component.

What I'm getting at here is two things primarily:

  • JSX, as a unique view language, isn't an SoC/SRP problem.
  • BUT, developers often introduce the problem with how they use JSX to build components and applications.

So far I'm looking at this question from the perspective of design patterns and Uncle Bob's SOLID, but that isn't the only way to look at it. You can (and should) look at it in terms of web technology purposes and intents.

Some people think that HTML is about rendering. It isn't. A brief review:

  • HTML - Semantic Content
  • CSS - Presentation (rendering)
  • JavaScript - Behavior

Developers I've interacted with, particularly those with extensive server-side or native UI toolkit experience, often get confused about the distinction between Semantic Conent and Presentation. It's no small distinction though. In fact, to hearken back to the previous section, you might think of it like this:

  • HTML - Model
  • CSS - View
  • JavaScript - Controller

Interesting isn't it? Hopefully, that makes more clear the importance of the distinctions in the web programming model.

There is a whole group of professionals in our community that care intensely about these distinctions. They are the Information Architects, UI/UX Designers, Web Designers, Graphic Designers, Marketing Specialists and Accessibility Experts. Note that these people aren't necessarily the same type of "developer" that is likely to have read Uncle Bob. They might not even think of themselves as a developer at all, yet they are an integral part of our community and the web ecosystem (more important than most developers feel comfortable admitting).

So, when you show JSX to a person with one of these backgrounds or areas of expertise and ask them "Does React violate separation of concerns by putting HTML and JavaScript in the same file?" They are going to say YES.

Someone who is tasked with the job of properly authoring Semantic Content is going to really have a problem with JavaScript getting in the way. A UI/UX engineer who is working with design tools like Sketch or Illustrator is going to be disturbed by the fact they can't write plain HTML and CSS. A designer or artist who wants to control rendering details and has to weed through JavaScript to find the proper HTML structures to apply CSS to isn't going to be happy.

The effect of JSX on this segment of creative individuals is to basically exclude them from the web. It nullifies their tools and renders anyone without extensive JavaScript capablities unable to create semantic content. That's a pretty serious problem. Most of these individuals could tell the average developer a thousand things they were doing wrong with their HTML and CSS because they are experts in these areas. Yet, the overreaching of JavaScript into the domain of HTML, makes it difficult or impossible for many of these individuals to collaborate or create - certainly not on the level of expertese that they actually hold.

Summarizing this perspective:

  • HTML, JavaScript and CSS have different roles and responsibilities.
  • Overly mixing roles can exclude a huge segment of the community from participating because they are masters of particular roles, often times not the one associated with JavaScript.

Ok, we've covered two important perspectives. But, there's another important thing to look at, which I hinted at in the previous section: collaboration.

Most people think that OOP, SOLID and various design patterns have a primary purpose of enabling code reuse. They can help with that. People often also recognize that these things can improve maintainability or extensibility of a system. That's true as well. But more often than not, people forget that one of the primary purposes for SOLID, OOP and many design and architectural patterns is to enable team collaboration.

When you properly separate concerns, you can have more people working in parallel on a given feature. A component model that has a solid separation of concerns can enable greater collaboration between developers, designers, UX experts, etc. They can work at the same time on the same component. At the present time, it's not sufficient always to simply separate these concerns, but keep them in the same file. Because of the way that modern code editors work and the way that version control systems work, it's much better to separate them into different files. Not doing this creates a technical barrier to productive collaboration. Your team will be slower and your development will cost you more money.

The main point I'm making is that how you go about handling SoC/SRP technically, has serious non-technical side-effects, including helping/hindering parallelization of effort.

Ok, let's step back and summarize the whole thing.

Does React violate separation of concerns by putting HTML and JavaScript in the same file?

The technical JavaScript Developer Perspective

  • NO, because JSX is a view language. That's one responsibility.
  • BUT, this implies that the JS developer is self-enforcing SoC/SRP on his own architecture by not mixing ViewModel concerns in his JSX. This type of vigilance "in the wild" is highly suspect because JSX involves the full JavaScript dialect.

The UX/UI Designer Perspective

  • YES, because JSX mixes Semantic Content (Model) with Behavior (Controller)
  • YES, because the intrusion, specifically of JavaScript, into the Semantic Model makes it difficult or impossible for me to play my role and leverage my expertese and skills.

The Team Perspective

  • NO, if both...
    • Separate files are used for the View (JSX) and ViewModel (JS).
    • Either there aren't UI/UX/Designers involved, or they are productive working directly with JSX (not very common).
  • YES, if either...
    • Everything is in the same file, causing problems for version control or productive use of modern editors.
    • Members of the team who are comfortable with HTML/CSS but less capable with JavaScript are excluded because of mixture or roles.

Now, a quick bit of followup to address other comments here:

  • HTML, CSS, and JavaScript all have the same concern, to render a view.
    • HTML is not about rendering, it's about Semantic Content. CSS is about rendering. CSS literally "binds" the semantic model to a set of rendering instructions via selectors. JavaScript is about behavior. It is only truly about rendering when not using HTML semantically or when working with a Canvas.
  • Browsers are used to render graphical elements...
    • Remember that browsers aren't the only user agents for HTML. HTML is important and meaningful irrespective of any rendering.
  • Separating HTML and JS is separating technologies. It is not separation of concerns.
    • If they have the same concern, then why are two completely different technologies required? Do they do the same thing? No. This is an issue of "zoom" as I mentioned above. Components themselves, internally, have different parts that serve different roles. They are concerned with different aspects of the component's life. Separating them allows experts to collaborate better (among other things).
  • JS is concerned with HTML, and they are inextricably linked.
    • I don't think you mean that. I'm sure you can think of lots of things to do with JavaScript that don't involve HTML, as well as lots of things with HTML which don't involve JavaScript.
  • ...React takes that to the next logical step - linking state, lifecycles, and all view logic with the small, specific, manageable chunks of "DOM" and composing those as necessary.
    • You just listed a lot of different responsibilities there.

Now, to the real point. Why is the author of this question asking it? There are a lot of possible reasons. Let's assume that they are honestly trying to decide if they should use React and have some honest questions/concerns.

If you are trying to decide...personally, I would tell you to avoid React. There are a lot of reasons for that which go beyond the scope of your specific question. But, let's look at it from the perspective of your question:

  • Technically, JSX is a View language (SRP) +1
  • It is easy for developers to mix concerns in a JSX file because the format uses JavaScript and HTML and most developers either aren't vigilant enough to stick to a solid architecture or aren't experienced enough to see where they are going wrong. +0 (benefit of the doubt)
  • JSX allows JavaScript to encroach on Semantic Content extensively, making content more difficult to author and read than plain HTML. -1
  • Those less comfortable with JavaScript, though they may be world leading experts in UI/UX/Etc. are now no longer able to participate in application or component development, or are severely stunted. -1
  • Teams using React could suffer productivity loss depending on their development habits (lack of vigilant adherance to their own SoC architecture) and team makeup (presence of non-JS-experts; though possibly more experienced than anyone in other technologies). +0 (benefit of the doubt)

Even if I try to be conservative with respect to what I know from experience happens in the real world, it comes out negative. For me, not considering any other issues React has, this is just too much risk and too much exclusion of potential talent and creativity.

Show +14 replies
Kaan Özcan's photo

@EisenbergEffect const HelloMessage = (props) => <div>Hello {}</div>; Here is your example. There is nothing confusing about this way of using and you can adopt similar way of style all around the application and you should. It's much more better option then %99 of other frameworks and much more simpler then all. It's only bad choice when there are no Javascript Engineers in company...

Rob Eisenberg's photo

@knozcan Thank you for the example. I'm not sure if you read my post now though. What you show here is exactly what I recommended developers do when I said "I think the cleanest way to use React would probably be to treat the component class as a pure JavaScript ViewModel and to extract the JSX rendering logic into it's own class/object/function, which serves as the View for the component." When you do that, that solves a lot of issues but I have never seen a single React presentation/demo/sample that actually did this. If this is the right way to do things, then I hope the React community starts showing that a bit more. That said, the JSX you show is a simplest possible example. If you have any sort of list rendering or conditional rendering, you are going to be changing that a lot and there will be a lot more JavaScript involved. The person who needs to work with HTML won't be able to avoid that. As I said in my post, if you have a designer that is comfortable with that as a View language, it's fine, provided the above practices are still followed. However, that is not, generally speaking, something that the design community and other web creatives are comfortable with based on my experience and research.