1. 47
  1.  

  2. 12

    This is an insightful article, and its lessons can be applied to far more than just JavaScript…

    1. 4

      I guess there will always be the group of people learning this. I wrote such an article myself years ago:

      https://ecc-comp.blogspot.com/2016/10/a-few-thoughts-on-ben-northrops.html

    2. 10

      I totally agree with this sentiment. Make sure you have good reasons for using the tools you use, not just because they’re trending.

      …buuuuuut as someone who has done a few green field React apps with hooks, I gotta say that it’s way easier to look at and understand than the class-based approach we had before. I still think the class syntax is good for regular old JS objects, but it does come with a price of needing to know far more about prototypal inheritance than you need to. I’m a big fan of the functional/declarative approach that React takes with its hooks and function-based components. That being said it’s definitely not worth rewriting a class-based application into a function-based one at this point, as both APIs are going to be supported for some time.

      1. 2

        Oh yes, I believe that hooks are the best new feature I’ve ever seen in React. It’s not a stupid trend and everyone should give them a try. However experimentation and gradual enhancement is the right thing to do in this case, even if code looks inconsistent. I’ve seen way too many times people trying to do this kind of massive change without any experimentation, or all at once in a single commit. These are really terrible practices and it’s crazy to encounter this situation nowadays given how many decades have elapsed since the birth of software development.

        1. 2

          I can’t disagree with you guys more strongly. I hate hooks with the fire of a thousand suns. They make everything more complicated than it needs to be, make the flows of execution harder to understand and predict, and reduce the amount of control you have over everything. I feel like the overhead of doing everything with hooks ads about 15% to my dev time, and 20% extra to my coding-related ragepression.

          What are the benefits that other people see that I’m missing, to make up for the awkwardness of expressing everything via hooks? People keep saying “reuse and composability” but I don’t actually see any to speak of compared with classes.

          1. 2

            I also find them super confusing most of the time.

            I’ve seen many cases where hooks were fewer lines than classes, but only one where it was clearer (The ‘what size is the page I’m rendering into’ hook was a little nicer than the equivalent context).

            1. 2

              Just want to comment on this wonderful idea of ‘ragepression’ - definitely a common ailment.

              Regarding hooks, I think of them as some kind of weird state monad, and I think they give access to a more principled coding style.

              1. 1

                I’d say that it is really easy to define custom hooks like, let’s say, withUser() which returns null when the current user is not yet loaded and an object once it is loaded. Without hooks, you need setState-based logic inside componentDidMount. You can hide this logic behind a decorator but it still requires a bit more code. And there is a risk of name conflict in the props if for some reason you want to use the same decorator multiple times. And systems like Redux are not an option in some situations.

                But if hooks don’t work for you, then don’t use them. I’m not saying that you must use hooks, I’m saying that you should try hooks. The old API works just fine (personally I’m using it at work and I still like it) and if React folks decide to drop support for classes someday, it won’t be hard to maintain a class-friendly fork of React (or Preact) given how mature this library is.

            2. 1

              My big problem with React is that it values the developer experience over all else, including binary size and end-user CPU time. React means that you’re spending other people’s electricity to save you some time.

              1. 1

                Looking at this comparison of JS frameworks by binary size, React isn’t even the biggest offender of larger distribution sizes. It would seem that choosing pretty much any of the most popular frameworks will greatly inflate the size of the .js files that are downloaded to client machines.

                (NOTE: Frameworks like React and Vue “cheat” this particular test because they’re not as complete as Ember or Angular. For example, Ember includes its own routing library, data layer, etc, whereas in React you’d have to download additional packages that will route requests, manage state, and possibly make API calls for you.)

                For most “traditional” JS work, you really don’t even need a framework or any 3rd-party libraries to get most of the job done. So I’m definitely not a proponent of “Reacting all the things”. But if you’re going to build an app mostly in browser-executed JavaScript, using a framework is going to be a lot easier on your psyche than not. And I don’t believe React is any more of an offender than the rest of them…

            3. 7

              In general I think we’ll find the sentiment rather uncontroversial, especially with the Lobsters crowd. Here are a couple of additional heuristics I’ve used to evaluate adding dependencies:

              1. Where applicable (and to the extent you can predict) prefer things that will, eventually, make themselves unnecessary.

              The classic example is jQuery, which has actually shaped Web APIs so that we now have very close equivalent native methods to do much of what jQuery offers. To this end, axios is illustrative. The previous typical way of not dealing with the bare XMLHTTPRequest object directly was $.ajax which, depending on the jQuery version, would have a more or less awkward API, and would (IIRC) be inextricable from the rest of jQuery. So axios makes a lot of sense as an incremental upgrade. Now, since the native fetch() method came along and inasmuch as browser support is sufficient and the caveats (abortable calls, etc.) are irrelevant, you’re really not adding much overhead by simply using native APIs (with, maybe a polyfill thrown in until support stabilizes). Web standards are, to me, a sure bet, or at least a whole lot surer than many other things.

              1. With tech that is all-enveloping, and which requires a more serious commitment, identify the escape hatches.

              Can you reasonably defer to native APIs when the limits of the abstraction that the tech proposes are reached? For some tech, limitations will not be immediately apparent (see the obligatory XKCD comic), and having N things work splendidly does not preclude the N+1 th from being very hard or even impossible to achieve without massive reorganization. If that ever turns out to be the case, does the tech seem like it will allow you to do things “your way”?

              Go to the GitHub page of any established web WYSIWYG editor, or any other insidiously hard problem, and identify the long-standing, 100s-of-comments-accumulating, issues that nobody can figure out how to implement without a major rewrite, if at all.

              Another educative example is React making architectural choices that make it one of the few major libraries that can’t easily support Web Components, although being a library that plays reasonably well with native APIs – you can have a DOM subtree be managed by React, have a React subtree defer to plain DOM – it doesn’t preclude you from using WCs.

              1. 4

                (Problem is, of course, we’re much more inclined to apply critical thinking to things that rub us the wrong way or that we can identify as bullshit, and still let ourselves get sucked in by the siren call of things that sound good to our ears.)

              2. 6

                This isn’t really a JavaScript-specific thing. It happens all over with all sorts of different languages, frameworks, libraries, etc. It ends up coming back to the “old and boring” vs “shiny and new” argument. You’re more likely to encounter “old and boring” in corporate places and “shiny and new” in startups. JS/UI gets the least love out of any side of the coding world, so I think it tends to have more people who are unfamiliar with those same problems that have already been happening for a long time in other sides.

                That actually doesn’t go specifically for following the hype. I remember reading multiple articles over the years that discuss “new” JavaScript things being a rediscovery (or a “new discovery” in some cases) of coding practices that have largely been solved in other applications (i.e. non-web) for decades.

                There’s definitely a mix of more engineer-focused devs and more art-focused devs in JavaScript, but I think historically (and probably still today), the art-focused devs have outweighed the engineer-focused devs. I’m not saying that with any judgment, either. I’m one of the art-focused devs.

                1. 4

                  Generally speaking I agree with the sentiment. The react world is specially driven by this hype mentality. I started using React in 2015 but been following it since it was publicly released in 2013 I believe. I’ve seen a number of major changes in its methodology. From createElement to JSX to classes to hooks… In truth it feels like they are still figuring it out.

                  But sometimes it pays off to try something new. After a couple of years of mainly using React and Vue I tried Svelte and it is a game changer. I don’t say this lightly, I’ve been in web dev since the late 90s.

                  Svelte is very pragmatic so it optimizes for 90% of the use cases and IMO solves it better than the others, but what’s really revolutionary is the compiler approach. A priori it seems like it’s just some syntax thing like JSX, SCSS, or Vue single file components but it’s not. The Svelte compiler is actually analyzing your code and creating dependency graphs to output the most optimized and efficient version of your components in almost pure vanilla js. There is no runtime.

                  1. 3

                    Svelte is a super-exciting development, for sure, but my spider senses are tingling about its maturity. I’d gladly use it on smaller / personal projects, but since it’s closer to the all-encompassing end of the dependency spectrum, I wouldn’t go all-in on it for a huge project just yet. (YMMV)

                    1. 1

                      Same feeling here. I tried it for a small side project. There’s definitely way more documentation, support, and third-party code available for React. Svelte was way faster though, definitely seems promising.

                      1. 1

                        Yeah if you want a rich ecosystem then definitely Svelte is a bad choice, at least today.

                      2. 1

                        As someone who’s only barely used Svelte, what do people mean when they say Svelte has “no runtime”? As far as I can tell, there’s still code executing in the browser that decides what to show, when to show it, and how to display it. Sometimes that’s JS, but from what I can tell it’s not substantially different from Vue, React, or any other web tool. In some ways it’s more like Elm or ReactReason in that it’s a language that compiles to browser native languages, but there’s still code that’s executing at runtime.

                        1. 3

                          Rather than relying on a runtime library — where your code calls methods from a library — Svelte will “compile” (if you will) to code that uses native DOM methods directly. I haven’t used Elm but that sounds like a fair comparison. However, I think Svelte is substantially different from Vue and React; virtual DOM is pure overhead says the main Svelte author, Rich Harris.

                          1. 1

                            That makes sense, happy to have someone finally clear that up :D

                            I’ve heard that about vdom from Rich Harris before, though Elm’s vdom would disagree in that it’s easily comparable performance wise to Svelte. It does help that Elm is able to optimize away a lot of code that Svelte and React aren’t able to.

                            I do like some of the premise of Svelte though.

                          2. 1

                            Yes, obviously there is code executing. :)

                            With, React, Vue, etc, your components do get transpiled to JS but these are useless without the engine, so to speak. On top of the components these need what’s commonly called a runtime (even if the term might not be technically accurate) which includes say a vdom, component base class, reactive primitives, etc.

                            The Svelte compiler simply produces vanilla code you could actually write yourself by hand, given enough time and expertise. Other than some helpers functions to reduce the final size there is no engine, no virtual DOM, etc. The produced code is just a series of very simple imperative vanilla instructions. This makes Svelte very fast but also much lighter which I think is the most important metric for 99% of use cases. It’s not very often one needs to update thousands of dom elements per frame anyway (although Svelte can do it with ease).

                            The downside of this approach is the the size per component can end up being higher with Svelte since it will end up repeating some pieces of code in every component. Given enough components a Svelte app will end up being bigger than a React app with the same number of components. But quite frankly if your app is so big that you’ve actually hit this inflection point you should start using code splitting which totally negates this problem.

                          3. 1

                            Svelte looks so nice, I can’t wait to get a chance to work with it next time I’m green-fielding something. Hopefully they’ll have TS support fully-baked by the time I do, I don’t wanna go backwards and lose my types.

                            1. 1

                              “From createElement to JSX to classes to hooks” is not really an actual flow. It was more like “from createElement to JSX” as one thing (though even then JSX was at the front of the initial releases) and then “from classes to hooks”.

                              Now, hooks are problematic to say the least, though it’s a nice feeling API there’s a lot of unfortunate, avoidable magic that would be hard to roll back. But JSX provides a “real” improvement that none of the traditional stuff provides, which is actually typechecked templates.

                              There are a lot of issues with usage of frontend JS but it is by and far miles better than almost all other forms of frontend and UI development, by being (when done at its best) safer, nicer on bandwidth (you heard me right! Of course sending raw data and using cached templates on the client side is going to be quicker than server-side rendering and constantly sending over HTML to the user for most devices), and just a better abstraction than other UI development tools.

                              EDIT: I think Svelte is kinda interesting from a tool development perspective but I disagree with its approaches and moving backwards on safety guarantees that React provides. There’s a middle ground but I feel like we’re not going to find it because of “no runtime” navel gazing.

                              1. 2

                                It was more like “from createElement to JSX” as one thing (though even then JSX was at the front of the initial releases) and then “from classes to hooks”.

                                Indeed, it was an artistic license. :)

                                nicer on bandwidth

                                I agree, as long you know how to manage the first hit of JS bytes that needs to be downloaded and parsed.

                                Another problem with modern SPAs is that, unless done well, it breaks many things users take for granted.

                                1. When going back to a form these should keep the last content that they had before pressing submit.

                                2. Many routers in SPAs usually capture the click events and decide what to do with it which frequently breaks stuff like clicking with a modifier key, middle mouse button, etc.

                                3. When going back the previous content should be preserved instead of reloading it again and showing a spinner.

                                Etc.

                                All of those points can be certainly solved, but in my experience most SPAs do not care about these details.

                                Don’t get me wrong, I absolutely think that an SPA when done well can provide the best user experience. It’s just that doing it well takes a lot of effort. Also, considering the success of non SPAs like StackOverflow, Github, Amazon, Wikipedia, etc, I often wonder if going the extra mile is worth it.

                            2. 2

                              Never used docker or kubernetes or AWS or NoSQL. They’re all just trends.

                              1. 1

                                One huge benefit my team found after moving to ClojureScript was the stability of the language and the ecosystem around it. We’ve been using re-frame for about five years now, and its APIs and semantics have remained largely unchanged. There have been a few new features added, but practically no breaking changes over the years. We just update the version to get speed improvements, features, and fixes.

                                Meanwhile, React ecosystem has had a ton of churn in that time. There have been lots of patterns introduced like redux, flux, hooks, and so on. If you started building an app using best practices a few years ago it’s likely to be considered legacy today.

                                There’s a lot to be said about having a stable ecosystem and development practices that don’t keep changing for the sake of change. Chasing Js trends is simply not sustainable in my opinion, and it’s a huge drain on team efficiency. On the other hand, if you don’t keep up then you end up with legacy code where libraries you depend on are no longer maintained, and it’s hard to find developers who are still familiar with them. A lot of shops got burned by this investing in Angular when everything changed with Angular 2 coming out.