How we react - Hooks

I’ll take the bait :rofl:

I’ve looked extensively at hooks, including trying them out in real applications that I’ve worked on and I have to let you know that I think they are going to cause so many problems for React apps (and Vue, who pretty much copies whatever React is doing).

Yes, there is a ton of hype. There’s more hype in the JavaScript community than I’ve ever seen in any community or around any technology in my entire career. It’s outrageous and unhealthy. My best advice would be to focus instead on demonstrated designs, practices, etc. that are published in books and journals, which have stood the test of time for multiple decades. Pay more attention to people who have some real experience behind them, and not so much to some of the framework authors who have less than 10yrs under their belt (and some of whom don’t appear to have shipped a real app ever). It’s the blind leading the blind out there.

With Aurelia, we don’t need hooks because we have three very powerful things:

  • Observability
  • Dependency Injection
  • Metaprogramming

There are more, but these are things we have, which have been around for decades, and which neither React nor Vue has in full.

React can’t actually observe arbitrary objects. So, as a result, it needs to be told when to update through calling explicit APIs (e.g. setState). In the real world, this turns out to be completely untenable. So, the React community came up with Flux and various libraries like Redux. Of course, Redux forces you to centralize all your state and magnifies the amount of work you have to do to accomplish the most basic of scenarios. This causes issues of complexity, lack of modularization in the code, debugging challenges, and so much more. So, then the React community moved on to Hooks as its 3rd attempt. Hooks are difficult to understand and they force you to pull all normal logic out of encapsulated object boundaries, as all state must be modeled with hooks, or it doesn’t really work. So, complexity, intrusiveness, etc. There’s also some questionable performance characteristics (actually, all of these techniques have perf issues) and other items of debate even within their community.

With Aurelia, we can observe normal objects/class properties. So, you can leverage the last 40ish years of OOP techniques and battle-tested approaches to building software. Also, the general observer pattern has been around for a very long time and has scaled to some of the most complex apps today.

Vue has observability too, but can’t observe as many edge cases as Aurelia (for example, it can’t observe Set and Map). However, taking those shortcomings aside, Vue doesn’t have dependency injection and it utilizes a custom non-standard way to create objects. As a result, as a Vue app tends to grow larger, it gets more and more spaghetti-like. It’s hard to properly modularize and compose the objects. One has to result to globals and other strange hacks to simulate a DI-like functionality. They are looking to hooks to solve this issue for them, but it’s not going to end well.

On the other hand, Aurelia has a very powerful DI framework. This lets you decompose any problem into small pieces that work together to tackle something complex. Need to make something reusblabe? Just factor it out into a new class and inject it wherever you need. That’s a basic form of composition that works very well, with decades of history behind it.

None of the frameworks have metaprogramming capabilities like Aurelia. In Aurelia’s case, you can apply a decorator to a class, and the framework will use your declaration to “write” code for you, so you don’t have to. We take this further with conventions. So, you can write vanilla js, following a simple pattern, and Aurelia will write code for you to make things into custom elements, etc. Again, this sort of technique goes way, way back. When you combine it with observability and DI, some magical things happen. You get plain objects and classes that you can model in whatever way makes sense for your app, based on 40ish years of solid practices, and the framework can just make those into components (metaprogramming) that interoperate with one another (DI), and can reflect their state to the view automatically (observability).

To sum up, don’t let hype get the better of you. It’s good to keep tabs on what’s going on, but root yourself in practices that have stood the test of time and have been proven over multiple decades to work for small, medium, large, and gigantic-scale apps and teams. Aurelia chooses a specific set of approaches based on my 15+ years of UI engineering focus, working on apps of every size and in almost every industry. I have yet to come across a scenario where these few basic concepts didn’t get the job done, and with great extensibility, testability, etc.

Always keep learning new things, but don’t forget what you’ve already learned and what you know works. A lot of time in our industry has been spent fixing things that aren’t broken, in search of some hyped tech revolution. I prefer a more iterative approach of slowly evolving and refining things over time that I’ve seen work. Hopefully, you can experience some of that through Aurelia.

21 Likes