For one you don't have to write an arbitrary key={item.id}. What if you don't have a unique ID? And even if you do, it's just busywork.
Then, what about conditionals? Or slots? Or classNames instead of classes? The saving grace of JSX is that it allows the creation of multiple small components inside a single file.
> The saving grace of JSX is that it allows the creation of multiple small components inside a single file.
That's definitely not the saving grace of JSX. As I said, every react project is soooooooo overly abstracted into the tiniest little components. It's no wonder people /think/ react is slow.
i dont have a dog in this fight but JSX is PHP all over again with additional "creative solutions" where html and js keywords clash. but they both make html less readable in different measure for different people. please carry on with the arguments :}
For what it's worth, I like the syntax of Lit. There are a couple of magic symbols ("@" for method, "." for property); but otherwise, it's plain javascript.
The DOM output that Lit produces, peppered with magic comments, looks disgusting though :-(
JSX forces you into small tiny components because anything of any decent size becomes unmanageable. There's way too much mixing of JS into the template.
Vue you can do
<button :disabled="!isFormValid">Submit</button>
In React I've seen people do:
if (!props.isFormValid) {
return <button>Submit</button>;
}
return <button disabled="disabled">Submit</button>;
This is just an example, obviously you can write this better in React. My point is there's /always/ so much conditional markup like this in every react project I've come across or worked on.
Edit: I donno how to format code on here sorry. (oh figured it out, bunch of spaces)
Trying to be fair here, but what about vue makes it less likely that you won't put the same conditional logic into your vue template? If it's just impossible, then you're saying the framework is more limited, which is fine but sometimes you want flexibility.
This seems to be a 'best practice' issue as well that can be avoided through PR review. My team has been putting logic more and more into local hook files to keep components clean.
There's nothing inherently stopping people from writing clean react projects. But I've never seen one. But watching people fumble around trying to find where they need to make a change when things are so overly abstracted, and STILL try to justify that react is good, is baffling.
People break tables up into ~50+ files. It's crazy, and everyone does this, and its an absolute nightmare to maintain. Its 100% engrained into react culture that this is the right path forward.
React will never get better if people accept over abstraction as the right path forward.
So, I have not used React more than a tutorial here and there. Same with any of the other SPA libraries.
I do not understand why everything needs to be a single page application. Sure, my current employer is behind the times in the technology we use, but honestly, we survive just fine with server side rendering and plain, ol'boring, vanilla Javascript and a little JQuery here and there.
Of course, some things we have written are difficult to maintain at times, but I doubt any other library would have really made it simpler (more of an issue with the requirements than the technology). Abstraction is simple, for us at least.
I'm surprised you see that as a disadvantage, for me that's always the biggest advantage of JSX-style syntax! I don't want huge components that do everything, I want components to do as little as necessary to be actually useful. It's the same as if I were writing functions: keep them fairly small, make sure they're doing a specific thing usefully, and then compose them together like Lego bricks.
When I was doing more Vue work, this is one of the things that I struggled the most with, that splitting one component into two components required a load of boilerplate and a whole new file. (And that itself was a big improvement on Angular, which usually had multiple files doing different things, at least when I was last using it). This inevitably meant that I'd try and fit more and more stuff into a single component until it the pain of maintaining it was greater than the pain of splitting it. (At which point it would usually be a lot harder to extract the would-be child component than it needed to be, because I'd left it too long.)
I think the rest is mostly just syntax preferences. Like you say, you can write bad code in both cases, and I think a lot of it comes down to which matches better to your mental model if what HTML generation looks like. But being able to easily start a new component, just like starting a new function, is such an important benefit of JSX, for me at least.
> I don't want huge components that do everything, I want components to do as little as necessary to be actually useful
Having lots of tiny components makes it harder to see the big picture.
Too big and too small are both bad, there's a balance you need to find. Components should be small enough to fit in your head, big enough to represent ideas. The difference is that it's natural for big components to be broken down into smaller ones when their size starts to cause pain. But nobody goes around merging smaller components into bigger ones to make them more readable. When your components are too tiny people just suffer through the pain and develop Stockholm syndrome.
> I'd try and fit more and more stuff into a single component until it the pain of maintaining it was greater than the pain of splitting it
I understand that it seems painful, but this is actually a great workflow: it forces the decision to split to be based on the real pain, not on your fantasies about future pain. Pain is a tool that helps you make good decisions. In that sense React is like Perl: easier to write, harder to reason about.
To a certain extent, I agree that you also don't want overly small components, but it feels a lot like the debate about function size. Sure, you don't want to wrap every statement in its own function, you want functions that are big enough to actually do something useful, but as a rule of thumb, smaller is better than larger.
This isn't a theoretical concern either. Like I said, I've had this issue with Vue before, and component sizes just bloated to the point where many pages were just single, chaotically interwoven components with dozens of state variables that theoretically were never used by each other, but in practice tended to be shared accidentally or out of short term convenience. At which point all bets are off and every bug becomes an exercise in figuring out what's going on.
That's not to say that that's a Vue-specific problem, because I've also had that issue in other frameworks, including React. But far less often in React, because it's much easier to deal with the pain when it starts with a simple refactor, than dealing with it a year and several new features down the line when everything is tangled together like a headphone cord in your pocket.
I also love small and well thought components. But as an engineering lead and manager it’s a lot of effort wrangling devs to do so. They always start small and then overtime converge on multiple return statements full of huge amounts of inline JS.
I've been enjoying SolidJS recently, and due to framework limitations, it is generally impossible to have multiple return statements, which I think helps a bit here. The signals stuff also lends itself really well to writing code that operates only on state, and then plugging it into a thinner, dumber DOM layer, so it's easier to compose pieces together. It's like hooks or the Vue composition API, but moreso? It's difficult to describe.
That said, SolidJS as a whole requires a completely different mental model of rendering, even if it does look superficially similar to React. It's also a much smaller ecosystem, with less documentation, so getting to grips with it is that much harder. Very rewarding, but probably not ideal for everyone right now.
> one of the things that I struggled the most with, that splitting one component into two components required a load of boilerplate and a whole new file.
<a v-on:click="doSomething">
preferable to the jsx version:
<a onClick={doSomething}>
or even this loop example from the vue docs:
better than its jsx counterpart?