Of course, all of the above functionality can (and has been) implemented in jQuery, or vanilla js. But using a framework makes it easier to structure and edit the project.
Of course, all of the above functionality can (and has been) implemented in jQuery, or vanilla js. But using a framework makes it easier to structure and edit the project.
The server still needs to validate, no? I've never seen a form that really benefitted from client-side validation. As long as required fields are clearly marked, I don't really understand the value here.
> error messages
Hmm? What about them needs React?
> update of data pushed from server
You can poll very cheaply. And even Websockets are pretty simple. Check out Phoenix LiveView or Rails Action Cable for decent examples of trivial solutions to this.
> sharing markup/functionality between pages
Even Apache server-side includes let you do this. We're not talking about hand-rolling plain HTML files in MS notepad (or even going wholly js-free). We're talking about React being overkill in a lot of places.
Required fields are typically not the only type of validation required by a form. I think a designer would see the value of client-side validation more easily than a developer. It's not to ensure correctness - it's to give the user quick and actionable feedback.
> You can poll very cheaply. And even Websockets are pretty simple. Check out Phoenix LiveView or Rails Action Cable for decent examples of trivial solutions to this.
React isn't helping you poll - it's helping you structure your application in a way that ensures all components receive the updated data.
Right.. But I think often times the difference is pretty overblown. Clicking "save" and getting that feedback in ~100ms is not, in my estimation, worth the massive extra overhead of using a front-end framework, duplicating your validation requirements, etc. If you're google or facebook or youtube or are otherwise printing money, go for it. But for the 99% of web apps out there, I think this is a bad trade.
> React isn't helping you poll - it's helping you structure your application in a way that ensures all components receive the updated data
Right.. But so is just re-loading (most of) the page from the server. Again, e.g., Phoenix Live View or Action Cable style.
Is it worth spending more developer time (think $$) on optimizing things for imaginary savings on initial page load time?
> Right.. But so is just re-loading (most of) the page from the server. Again, e.g., Phoenix Live View or Action Cable style.
How is that less complex than a client side application? You are essentially advocating for splitting the logic between server and client side. Of course that is possible and people do that all the time for various reasons. Does not mean that's the best way of doing things.
I think you are missing the elephant in the room. Emergence of the front end development frameworks like React was caused by ever increasing complexity of the front end applications. Which, in turn, is driven by customer demand. Customers pay for features, not for code quality, and churning out features is much easier and quicker using React vs. e.g. jQuery.
Lamenting front end application overhead is the same as lamenting using high level languages for back end services. Everybody knows that Real Programmers wrote Real Programs in assembler back in the olden days!
> in ~100ms is not, in my estimation, worth the massive extra overhead of using a front-end framework
The phenomenon of change blindness means a 100ms "blank screen" can be the difference between the user recognizing the fact that they've made an error and getting frustrated because they can't tell where the error is. The 100ms reload means if you don't want that to happen, you have to be much more careful about how you design your errors.
It's an easier design problem if the user sees the error appear immediately where their attention is already focused.
https://www.youtube.com/watch?v=bh_9XFzbWV8
I'd argue caring about this is more important for a smaller product where the marginal cost of a single user churning is (probably) much higher.
Let's say the form has 5 fields, and I as the user make an error in the first field.
Why do I have to finish filling out the entire form to hit "save", to discover I made an error in the first field? That's not a difference of ~100ms, that's a difference of several seconds (or tens of seconds for a medium-complexity form).
Because more validation will usually happen on the server side anyway and finding out when you hit save creates less interruptions to your flow. There's no tabbing back to re-enter a field, there's no thinking it's fine only for the server side validation to reject it and there's no nagging when I skip a field to come back to it later, there's no UI jumping around when the error is shown. Client side validation takes a stateless form and interrupts me with it's stateful validation. At best it's an interruption, all too often there are silly things like not letting you tab to the next field or warning you that the second password you haven't yet entered doesn't match (and then later telling you about other problems when the backend does the validation).
Not to mention it's easier, whether you agree or not with "developers are expensive so performance doesn't matter" in a world where this is often said I'd expect more server side only validation because client side validation is duplicating the work.
I don't think client side validation is necessarily bad, but most implementations get in my way more than the server side equivalent.
Well, that's a criminal use of client-side validation, but it shouldn't condemn all client-side validation.
> Not to mention it's easier, whether you agree or not with "developers are expensive so performance doesn't matter" in a world where this is often said I'd expect more server side only validation because client side validation is duplicating the work.
That's fair, but as others have noted if you're in a world where a polished user-experience really makes a difference or is a competitive advantage I'd argue that well executed client-side validation can get you to a UX-quality bar that no amount of server-side validation can reach (edit to add: server-side validation is still, of course, absolutely required).
Whether that's truly important for a given business or product can only be argued on a case-by-case basis. I think it's definitely a colorable argument that there's some overuse of client-side validation relative to product goals, but I think there are definitely places where client-side validation is hugely impactful.
Again, all of this assumes that the client-side validation is implemented at a high quality bar. Of course bad client-side validation is not useful.
I just think that, if you're aiming for the highest UX-bar, you're going to need client-side validation at some point. For any mildly complex form, server-side validation will usually be far past the sweet-spot you're referring to.
Now, as others have mentioned, it might be questionable whether every web-app and website should be targeting the highest UX-bar.
Any non trivial form is going to have non trivial validation. Validity for some fields will depend on other fields, the validity for a single field could have complex rules, and forms can be lengthy. It helps the user to get validity feedback without sending information back and forth from the server.
> Hmm? What about them needs React?
> You can poll very cheaply. And even Websockets are pretty simple. Check out Phoenix LiveView or Rails Action Cable for decent examples of trivial solutions to this.
Like I said in my OP, none of the things I listed require React, some dont even require JS. But having worked in large codebases of jQuery and large codebases of framework code, frameworks scale up better. LiveView is cool tech though.
> Even Apache server-side includes let you do this. We're not talking about hand-rolling plain HTML files in MS notepad (or even going wholly js-free). We're talking about React being overkill in a lot of places.
If you need to share markup with dynamic values, you need a full programming language. I'm aware that there are many solutions for sharing markup, but there are fewer solutions for sharing markup with dynamic behavior. Again, a framework scales up better.
To be clear, I'm not suggesting React for everything. But the GP comment was suggesting it was good for nothing, so I provided counter examples.
Client input should never be trusted. Server needs to validate, but that doesn't mean client shouldn't validate as well.
> I've never seen a form that really benefitted from client-side validation. As long as required fields are clearly marked, I don't really understand the value here.
Client side validation is not only about required fields, it's much more than that. Have you ever used a web store where you need to enter your shipping address, credit card info, etc? Address, zip code (or worse, UK style postal code), phone number, email, credit card number - all that needs to be validated.
Sure the server can (and should) validate that. The problem then is how to let the user know they've made a mistake and how to fix it. Accessibility issues aside, users need to be told that they've made a mistake as soon as it is made, otherwise there is a chance they won't find the error message, and simply give up trying. Lost sales is the reason client side validation was invented.
> Hmm? What about them needs React?
If you don't want to submit a form with full page reload, you need to make an Ajax call with form info. When response comes back with a list of errors, you need to walk through the fields on the page and mark the relevant ones as invalid, with corresponding error messages displayed _close_ to the input fields. Of course that is doable in plain JavaScript, and doing that seems trivial for one form. Then you have to duplicate that code for another form, or abstract it in a library... Congrats, you're on your way to reinventing React. Or worse yet, Angular.
> You can poll very cheaply. And even Websockets are pretty simple.
When the results of that poll come back, you need a way to display them. You need to decide which part goes where, which elements to hide and which to create, etc. The mechanics of this is what React (or a similar library) does for you, so that you could concentrate on writing logic instead.
> We're talking about React being overkill in a lot of places.
React might be overkill in a lot of places, but it's extremely hard to tell where and when. If you start with a simple hand rolled JavaScript app, at some point you might realize that maintaining it is a chore beyond one person's capacity, and hiring someone to do that for you is plainly impossible. You should have started with (React|Angular|Vue|whatever) in the first place, and now it's a choice between ground up rewrite in (React|Angular|Vue|whatever), or long stagnation and eventual death of your business. Do you want to take that chance?
Optimizing for developer productivity is the only safe bet in the majority of cases, unless we're talking about a personal project with no commercial value.
A couple points:
1. The ~100ms between submitting a form and getting error messages isn't that big of a hurdle, in my experience.
2. HTML5 has validation attributes for forms, which can handle every one of your examples.
> If you don't want to submit a form with full page reload, you need to make an Ajax call with form info. When response comes back with a list of errors, you need to walk through the fields on the page and mark the relevant ones as invalid, with corresponding error messages displayed _close_ to the input fields. Of course that is doable in plain JavaScript, and doing that seems trivial for one form. Then you have to duplicate that code for another form, or abstract it in a library... Congrats, you're on your way to reinventing React. Or worse yet, Angular.
Negative. You can do an ajax call, and re-render part of the page (e.g., the entire <body> pjax-style). This is fast, doesn't cause the "flash" of a page reload, and doesn't require more than a few lines of js to setup.
> When the results of that poll come back, you need a way to display them. You need to decide which part goes where, which elements to hide and which to create, etc. The mechanics of this is what React (or a similar library) does for you, so that you could concentrate on writing logic instead.
Again, turbolinks on pjax has solved this problem very well. Just re-draw the bulk of the page. All the simplicity of reloading the page with none of the user pains of actually reloading the page.
> Optimizing for developer productivity is the only safe bet in the majority of cases, unless we're talking about a personal project with no commercial value.
I agree. But I don't agree React _benefits_ developer productivity. On the contrary, I think it (and its competitor frameworks) are responsible for a lot of wasted developer time and frustration.
Sure, it's the >100ms between the user entering the first value that might have an error and the user submitting the form that's a much bigger problem between validate-on-server-on-submit and validate-on-client-on-entry.
> But I don't agree React _benefits_ developer productivity. On the contrary, I think it (and its competitor frameworks) are responsible for a lot of wasted developer time and frustration.
After a not-very-long familiarization period, developers seem to be more productive with React (or probably Angular.) I know I am, and I've been using SPA frameworks (mostly React) for a short time after having done web lots of other ways for a very long time.
Not every organization can use this approach either. E.g. I work at a True Java Shop(tm), where voicing the idea of using Ruby for a back end service would get me laughed out of the room with a permanent label of That Funny Guy Who Likes Toy Languages.
Using React for a front end client application that consumes back end API built in Java is 10x more productive than doing the traditional "Java Way" application with server-rendered HTML.
The issue here is not the length of time it takes for the response to come back, rather the fact that there is any delay at all. Client side validation code can be synchronous, submitting any validation info to the server makes it asynchronous by definition. State synchronization between client and server is a big enough problem as is, there is no need to add to it.
Consider this scenario: you have typed an email into a field, tabbed to the next field and realized that you made a typo. Our client sent a validation request to the server, and meanwhile you shift-tabbed back and corrected the typo. The server response came back with invalid indication for the already outdated state, what do you do?
This kind of issue is happening in real life a lot more often than you might think.
> HTML5 has validation attributes for forms, which can handle every one of your examples.
There is no input type for credit card number but there is a very basic and easy to implement algorithm that checks the credit card number validity. This alone is worth implementing client side validation, if your application has to handle payments in any form.
> Negative. You can do an ajax call, and re-render part of the page (e.g., the entire <body> pjax-style). This is fast, doesn't cause the "flash" of a page reload, and doesn't require more than a few lines of js to setup.
Double negative. Re-rendering part of the page received via Ajax call obliterates the current state of that page, or worse yet, a part of the page. User started typing and the page reloaded, all their input - and even which field was focused - is lost. This is a very undesirable user experience.
> Again, turbolinks on pjax has solved this problem very well. Just re-draw the bulk of the page. All the simplicity of reloading the page with none of the user pains of actually reloading the page.
It's actually vice versa: all of the pain of actually reloading the page with no real benefit whatsoever. If you are going to reload the bulk of the page, might as well reload the whole page, just to have consistent state. But that brings us to square one: why having all this complexity in the first place? Because we want user interaction to be smooth, quick, and painless. This implies eliminating roundtrip delay, however small it is.
100 milliseconds might not be much but it can easily turn into 10 seconds if the server is overloaded. 10 seconds delay after submitting a _validated_ form to complete sales transation and display a success message is not a big deal, the user has already made a decision and now they're going to see the positive result. Your site is slow == that's ok, I made the purchase anyway.
10 seconds delay to validate form values and display an error message would most probably result in a lost sale. Your site is slow == it's bad, I won't spend my money here.
It's as simple as that.
> I agree. But I don't agree React _benefits_ developer productivity. On the contrary, I think it (and its competitor frameworks) are responsible for a lot of wasted developer time and frustration.
That's a highly subjective assessment. Do you have a way to measure productivity gains or losses? I don't either, just some anecdata.
About a year ago I needed to build an app for my ongoing personal (at some point to be commercial) project. Think a simple portal for adding, editing, and deleting entities. I decided that since it was internal use only, I can ditch the fancieties and do a quick and dirty old style app: server side logic, form submissions, full page reloads, etc. Back to 1999.
I spent a month of evenings trying to get it done, and didn't get halfway before ditching the effort and rewriting it as simple front end single page app + simple back end that exposed stateless API for the client to consume. That took me 2 weeks worth of evenings.
Lesson learned: never again, there's just too much mess with server side HTML templating, state propagation between page loads, form validation, etc etc. I don't even want to think about partial updates that _still_ involve server side HTML templating but combine that with a double dose of state propagation and synchronization. I didn't even get to writing any tests for that server side, simply because abstracting templating code from actual logic code was painful.
It can be argued that I did not use the best server side framework, did not know what I was doing, etc. That's actually my point: if doing old style web apps was so much easier, I should have been able to complete it fast without much sweat, no?
Having seen many similar discussions I came to the conclusion this might really be something of a generation gap. For those of us who spent their youth developing web apps back in the day, doing it the "old" way (that fortunately still works) seems natural and easy. And in some cases it's ridilously easy. If your needs are fairly typical (like the CRUD you describe), you might not even need to do that much - Django Admin or Laravel Voyager will take care of these.
No thanks, not gonna do that ever again. Rosy glasses are rosy, and cleanly separated client side app + back end API is clean and separated.
Spent my youth doing it the old way. Much rather use either React for nontrivial apps, still, now.
> They're forms that submit stuff to a server and get a response.
So it sounds like they're not actually doing any of the things you mention. For basic forms that just submit, of course React is overkill. Hell, a software developer is overkill for that. For any of the things you mention, React or another similar UI framework makes the project much more manageable.
We decided to split it into an MPA, adding React components to server-side rendered pages as needed (along with intercooler and stimulus when we don't need the power of React).
Things have become much simpler and quicker to develop, allowing us to focus on the user features instead. It's easy to forget how much you get for free from the browser and traditional HTTP/HTML client-server mechanics, along with the ease of having full access to your database and data model in your templates - and makes you wonder if going with an SPA first is throwing the baby out with the bathwater.