loading...

Why would people hate React (or JSX), but not Vue SFC, or even Angular?

patarapolw profile image Pacharapol Withayasakpunt ・1 min read

Or even, do you hate lit-html?

I mean, all you are doing is either HTML-in-JS, or truly JS function syntax anyway. No real separation of concern here, unless you truly visually separate them.

I think HTML-in-JS is the basis of SPA, anyway.

Discussion

markdown guide
 

I'm glad you asked , LOL. I worked as a professional React dev for about 9 months ( part time ) and I've been a professional Angular dev for over a year.

I hate React, and JSX the primary reason. CSS in JS is another ( not required for React, but prominent ). First, however let's talk about JSX.

Separation of concerns was the ENTIRE reason we decided to put controllers, HTML, and CSS into different files. JSX muddies the waters so much that there are some JSX novels that I've seen and worked with that read very much like a horror story.

Heiker's example is a good example of this. What I love about Angular is that your component's html file is, well, an HTML file. Sure, it uses structural directives and some minimal ( very readable ) interpolation, but it's nothing compared to the spaghetti mess the JSX usually becomes.

When it comes to very complex views, nothing is worse than having to mentally map your way through a React component with endless JSX acrobatics that you have to translate into your mind into a coherent web page. For simple views, it's fine. But in some of the more complex views that I've seen, it's just ridiculous.

There's a reason why Angular tends to be the framework of choice with much larger and robust enterprise applications. It scales better, and it's easier to deconstruct and refactor the architecture as things grow and change. To me, React is beautiful , fast , and elegant for smaller and medium sized projects, but once the projects scale, it can become a Frankenstein very quickly. There's no real universally agreed upon pattern for how React should scale. ( Not to my knowledge ) , where Angular's structure is baked into the framework.

I didn't bring up TypeScript because technically you can use TypeScript with React, but TypeScript being in ALL Angular projects is the other major reason that I love it.

 

The only thing Angular has going for it IMO is that it's very opinionated in how you structure literally everything. That's fine, but it's very limiting, and sometimes you end up fighting the framework to do what you really want.

As for React, it's far less opinionated. In fact, it's not even a framework--it's just a library, so I don't really think the two are comparable.

As for the JSX soup problem, I think you can really chalk it up to a clash of paradigms and a lack of discipline.

React components should be very small, and only concern themselves with rendering the view on the page. That includes layout, data, and minimal logic (e.g. mapping a function over list items) required to render the correct view.

All of the business logic and technical bits like state management should live inside a higher-order function that wraps the component. The Angular equivalent of this is to have a "dumb component" with a service class to manage the business logic.

That's just a design pattern that people need to recognize and use, just like we have design patterns in Angular. It's just that React doesn't generate boilerplate code to enforce design patterns like Angular's CLI does. To me, that's a good thing, and I'm not alone in that belief. But it does open up more opportunities for programmers to do idiotic things.

 

So it sounds like the debate is really about a clash between the more traditional OOP paradigm (angular), compared to a library based heavily on functional programming concepts (react)

 

@jordan Lee , well yes and no.

I suppose you could make the argument that JSX is the end result of committing to a functional programming paradigm as it would relate to view interpolation. I understand that argument ( kind of ), but Angular's method of view interpolation could have been designed to fit within a functional programming paradigm .

In other words, my biggest gripe about React is JSX itself and functional programming does not require you to assemble Frankenstein entities like JSX any more than Angular's view interpolation is inherently OOP. In Angular, having things like ngModels and 2-way data binding make it classical OOP, but those things are not what I'm enamored with. I'm enamored with "separation of concerns" between the view, CSS, and the component. React cannot give me that. Angular can and does. That's why I went back to Angular after doing React for almost a year.

To the other point @austin made about JSX elements being ideally very "small" and modular, I get that too. But what I found myself doing with React was digging through 10 different components whose JSX all hooked into each other. Having to mentally map all of this when exploring more complex widgets and it can get VERY unwieldy. There's a reason why we separate components from views and I just don't like those two things being combined in React.

However, to each their own, and React is very popular so I'm not knocking it at all. If I have to use it again for an important project, I will.

 

Old man yelling at cloud here. I know that JSX can be use for good and has many good things but I'm here to talk about the things that bug me.

Using JSX to render html elements is all good. My problem is when people go beyond that, when they start doing one clever thing after another in the middle of that html.

Stuff like this.

<div className="tag-list">
  {
    (this.props.tagList || []).map(tag => {
      return (
        <span className="tag-default tag-pill" key={tag}>
          <i  className="ion-close-round"
              onClick={this.removeTagHandler(tag)}>
          </i>
          {tag}
        </span>
      );
    })
  }
</div>

Using .map to render a list? That's clever. Using parenthesis and an operator to make sure .map gets executed? I get it, you want to prevent a bug, but why do it there? They could have handle that in another part of the code but they didn't because nothing could stop them from putting that piece of logic there. And that piece of just HTML-in-js is going to get worse if they need to do more clever things in that taglist.

And then we have "renderless components", I do hate those things. It breaks the mental model of using tags to describe the user interface.

<Provider>
 <div className="editor-page">
    <div className="container page">
      /// stuff
    </div>
  </div>
</Provider>

That "Provider" thing, if I can't put a margin, padding or color I don't want it as a tag. And of course this "renderless components" are so flexible that we can do this.

That freaks me out.

 

I don't understand this attitude of "I hate framework X because people are able to do things I consider bad practices."
Every language/framework allows many kinds of bad practices, it doesn't mean you should use them.

 

I don't understand this attitude of "I hate framework X because people are able to do things I consider bad practices."

Did I give that impression? I wasn't trying to say that I hate React, I actually like it. I tried to be very specific on the parts that I don't like.

Every language/framework allows many kinds of bad practices, it doesn't mean you should use them.

While you can always choose the patterns you use, you can't always choose the tools used in a codebase.

 

Agreed on the renderless component thing. I get it and it's purpose, you can do them in Vue, too. In some cases, I don't mind it, but when you're using a component to define the behavior of your router, I just don't understand why in the world you would want to. Defining route logic in your render function just seems illogical to me. What's wrong with doing it like Express/Vue and pretty much every single other framework in the existence of the web? 😵

 

I personally love the declarative nature of handling routing inside the component.

The DOM forms a tree structure, and so does the function call graph of your application. Routing (as a general concept) represents a "forking" mechanism in the middle of that DOM tree structure somewhere. There is a "choice" to branch off in different directions. Since (in React) we are already representing our virtual DOM as a return value of the function call graph, why would we not handle routing in the exact same way, since routing is almost precisely the same idea as a function with a switch statement?

If that doesn't make perfect sense, then I'm at a loss for words...

 

Seems like anyone can do whatever they want - is not a bad problem to have

 

Tell me you're not defending the XML Sort function.

People seem to jump at the chance to defend the indefensible on the Internet.

There would be no good choices without bad ones

 

Vue's Nuxt also have <client-only> (i.e. <no-ssr>).

Good thing, maybe; is that Vue / Nuxt prefers DSL in <template> tag.

 

I'm not familiar with Nuxt. I imagine that <client-only> is also a renderless component. Still not a fan of that type of component.

What I like about Vue SFC is that is familiar. The template, script and style tag is a good mirror to the traditional html structure.

 

Vue and Angular are very good because they impose a certain style by using strict conventions and style guides.

So anybody else can come later and understand your code.

The same can't be said about React, even if it has big companies using it.

Also, my biggest problem when I used it was that it doesn't have just one STORE. But a lot of clones online(easypeasy, mobx, another better management store).

So my question is:

Can react devs and contributors stop forking and working on a single universal store and best practices for it?

 

Overall, I think the biggest issue I've found with React is it just doesn't have an opinion on a lot of things: routing, state management, logical categorization of components.

The second big thing that I find awkward with it is that it doesn't have a discrete services layer. Prop drilling and context are fine in small applications, but I'm just really not sure that embedding the services layer in the view hierarchy is at all scalable.

I hear a lot of people bashing Redux, and I get it - it took me a while to come to grips with it (no thanks to the Redux-specific jargon), and it involves a lot of boilerplate - but I really think it's better to separate your data access and transformations into totally separate files, detaches from the view hierarchy.

All that said, I have no problem with JSX. It serves as a nice visual distinction between the component hierarchy and any business logic a component might have (unless you mix your business logic in with your JSX - please don't do that).

 

I'm really keen on separating out logic from my view layers in complex apps. The fact that almost most react blogs and docs don't mention large multi-target apps (cli/api/web-app that all share code). #cleanArchitecture

 

Totally agree. It just makes things so much easier to think about.

I still really like React for its composability, though!

 

I feel like react often introduces new ways to do the same thing and everybody refactors and updates all their libs to the new hot way of doing things. The most recent addition is hooks, which was supposed to reduce 90% of your code's complexity. Unfortunately, it only makes simple code simpler, everything else became harder and requires you to know the nuts and bolts of react, hooks and javascript. Some argue that's not a bad thing, but it's by no means progressive like vue. Consider all the devs out there whose "first language" is not JavaScript...

E.g the following will execute the useEffect every time it renders if you don't pass the item prop because it is considered new. Imagine setting state in the useEffect, you got yourself an infinite rerender without any sort of error message hinting to the solution, or even the problem.

const { item = {} } = props

useEffect(() => something(), [item])

 

I'm not sure I can agree with your comment about hooks making React more complicated. Of course, if you've only ever written class components and are using hooks for the first time, you can expect there will be some learning curve - as with anything. But I firmly believe the learning curve is worth it. The main points I disagree with:

  • React continuously introducing new ways to do the same thing: I view this in a totally different way. Yes, ultimately React/Angular/Vue all do the same thing - decoupling application state from the DOM. But if the React core team is constantly looking for better ways of achieving this goal, surely that's a good thing? Otherwise we might as well all be using React.createClass still and never upgrading past v3.0.0.

  • The next question then is "are these new ways of doing things better or worse than the old ways?" Regarding hooks, my experience is that they're much, much better than using classes when writing stateful components. By "better" I mean that after becoming accustomed to the style, it is much easier and faster for me to build an app. I can also scan and understand others' codebases written in hooks much faster.
    Additionally, with hooks there's less boilerplate code and React apps written with hooks are technically more performant than ones written with class components.

  • Surely you'd rather have library maintainers who update their packages to support new features, rather than using some npm library which has been untouched since 2014 and doesn't support ES6?

  • I can't comment specifically about the code snippet you provided, but I'm fairly certain React always warns you when doing weird things with setting state that cause infinite re-renders.

The caveat to my favourable opinion of hooks is there's still a couple of things I hate about them: firstly, how cumbersome/hacky it can be to properly add event listeners inside useEffect, and the currently poor solutions for async data fetching inside hooks (although this looks like it will be improved with the next major release).

Feel free to let me know if you disagree with anything

 

JSX Syntax is terrible. It reminds me of the old days when we had PHP inside ugly tags. Then we came out with template engines and the world was a better place.

SPA's have this problem generally, with qoutes inside qoutes inside qoutes making terrible to read templates. I prefer clean and simple templates with nothing more than a few capitalized key words inside mustache brackets. You don't need anything else, and anything else more complicated should be inside code and delivered as a value to the view. Languages inside of languages always annoyed me, and for more complex projects it quickly gets out of hand. Your essentially trading the spaghetti code of one kind for spaghetti of another, which then requires you to write ever more complex code to check the code.

It's the sort of design pattern that reminds me of John Stewart Mill's warning about how "The bureaucracy is expanding to meet the needs of the Expanding Bureaucracy."

Vue has the least annoying template syntax, so it's my go to for persona projects.

React as a whole is quite good and I'm a big fan. But I write as little JSX as possible, and when I do, it's almost always an actual value with data-binding instead of a method call to a method call inside a method call. Every time I see an arrow function inside a template I die a little on the inside. And before someone mentions how bad code shouldn't damn a language, I'd like to point out that React design docs actually encourage this pattern.

Angular has a different problem. There are about 5 ways to mark up html elements, to the point that you get that absurd banana-in-a-box syntax for stuff like ngModel, and again you end up with quotes inside of quotes because you have to appease the parser ... rather than having a unified syntax and forcing the parser to appease us.

 

I shared your sentiment towards JSX being a reminiscent of PHP days. Some time later I come to like it, but from some unexpected angle. I was looking for a better way to write XML data. But it turns out, that if you want to describe a tree structure with attributes attached to each node, SGML derived languages are very good.

So if you want to describe DOM generation in code, JSX is a really readable format. It is not simple string gluing. And I agree, that one should not abuse the power of full JavaScript in interpolation - just use it for data binding and simple iterators/transformations.

 

That's totally fair, and I have no complaints about the architecture of react or JSX for that matter. It's an extremely solid and well engineered library.

Though as a general rule I try to avoid describing anything view related in code, and likewise I avoid describing complicated logic in views. When i build something in any language or framework I try to find a really stable subset of it, and write everything in that and I try to avoid getting clever.

It's probably a good rule of thumb for any SPA framework actually.

 

You use vanilla JavaScript and vim? Well I write everything in machine code, like a real developer

 

I don’t think they outright hate JSX, but rather, they simply prefer a different solution.

 

Well, I don't HATE JSX or any other markup. It's just a preference. That said, I prefer proper using HTML attributes like class, style etc. Instead of something like className.

 

people who hate Anguvueact, usually they either had to work with a bad codebase using it, or somebody they dislike is an advocate of it.

 

Just sort of musing here:

I actually really like the dev experience in React - it's fun, and who doesn't have fun at work?

However I'm not really convinced that SPAs, as a solution, are really in users' best interest, you know? For things that are actual applications, sure (Jira, Evernote web, Google Sheets, etc.), but for a static content or ecommerce sites... I'm not so sure.

As far as I can tell, it increases load times, complexity, processor use, battery drain, and data usage. That's fine for anyone making a developer's salary, but it makes your site a lot harder to use for anyone who can't afford a current-gen phone or a nice data plan.

 

Agree, but that's another question. I assume/hope that developers using React etc. responsibly, and not for static content leaflet pages and such. For practise ok, but not for end-user-focused products.

Fair point! I've definitely worked with codebases that turned me off an entire platform (Android comes to mind).

 

html belongs to html file! :) react is not my way.

 

A "long" time ago people used to put php/ruby with html and let it be generated on server. First they moved it to separate files then they started using SPA. It is in a way better to have application logic like UI stuff and validations run on client as you get scalability for free. However you still need to validate again stuff on backend. Now should be again forget the front thigs and get back to server? I don't think so. Same goes for HTML in JS. I'm more into Angular only because everything is separated. As for Vue i can see the point of having 1 file split in 3 sections. However Angular is slower then the rest and I'm just a backend guy.

 

React does not separate HTML, CSS and HTML. Vue(for example) on the other hand, at least does.

While both have everything in a single (JS) file, in Vue it is at least separated. At the top you have your HTML, then your JS, and finally, your CSS.

I haven't used React yet, only seen codes, so I said the above based on those.

Also, React has barely any logic in the code IMO, which makes it very hard to learn.

Don't know anything about angular.

 

The thing is, JSX is not like HTML. JSX is not a document.

JSX is code. It is a "fancy" way of writing React.createElement(...), specifically designed to resemble HTML, as both HTML and JSX are ways of creating DOM tree in the browser. HTML uses the browser's parsing engine, but JSX uses the browser's JavaScript engine.

Thus JSX (being code) belongs to .js(x) file.

 

I currently know Angular basics and Vue basics and I didn't find the initial learning difficult but when I tried learning react I found it more difficult and I didn't like React's way of doing things. Using vue's sfc was easier to understand for me than using React's JSX (although I prefer the Angular way).

 

I suggest using Webscript: mudgen.github.io/webscript/docs/

This is creating the DOM in Javascript the right way.

 

The website is broken on mobile.

 
 

Thank you. I am making it work on mobile now.

 

because vue and react has better documentation.

 

RiotJS and possibly Svelte (I don't know it well, but looks awfully similar to Riot) have it right

 

Svelte just force me to use a special extension and compiler. They don't even have full TypeScript support.

Vue also has SFC and a special extension. *.vue's Vetur has decent, but not full TypeScript support.

IMO, when template / DSL is introduced, it isn't HTML anymore.