Hacker News new | past | comments | ask | show | jobs | submit login
React is becoming a black box (jaredpalmer.com)
439 points by aigoncharov on Sept 3, 2020 | hide | past | favorite | 370 comments



I think hooks aren't really making React more of a black box, but just that it's invalidating a lot of people's incorrect mental models on how React works. (It's like C's undefined behaviors in that sense.) And the reason why a lot of people have these incorrect mental models is that React is a very thick abstraction.

For a long, long time, I thought that to provide the values that React brings, the UI framework being a black box is inevitable. Almost all React-esque libraries including but not limited to React, Preact, Mithril felt like a very thick abstraction over the DOM APIs.

But then I saw Crank.js[0], and that felt very intuitive and a thin abstraction, while retaining the good parts of React-esque libraries. I don't really know why it feels like that - I'm guessing it's because it uses native JS features that you already have a good understanding instead of some magic that happens in the React runtime.

I'm very looking forward to it, and I would like to urge everyone to try out Crank.js if you feel that React is now not intuitive enough.

[0] https://crank.js.org


(disclaimer: mithril author here)

The point of an abstraction is to create a "black box" of sorts around some primitive. I think all it boils down to with what the author is saying is that the React team is changing how things work under the abstraction, and therefore some assumptions people made about leaked semantics are no longer true.

Mithril rendering semantics have always been more or less this: on an event, redraw everything. React semantics started that way too, but now there are a whole lot of other semantics under the hood (for example, the rule of hooks provides some semantic guarantees that enable a hot reload implementation to be more robust). Concurrent mode is another example of semantics that benefit from rule of hooks guarantees.

I think when I see people complain about the rule of hooks is that there's a dissonance between the strict semantics of hooks and the expectations of what the semantics should be (for some definition of "should", usually related to ability to reason about stuff in some specific way)

I'd say that overlapping several different compatible underlying functional semantics under one umbrella of very strict API semantics is an interesting and somewhat novel approach to supporting some cool infrastructure (i.e. ability to do deep hot reloading stuff, animate in IoT devices in a renderer-agnostic way, React Native, granular reactivity via memo, and the list goes on). Where I think React missed the ball a bit is that the API semantics don't always feel ergonomic for the use case they're meant to serve (for example, I've seen a few occasions where nested hooks ended up w/ long code review threads debating obscure minutiae)

When I see people praise Svelte, I think the reason is similar: since it doesn't need to artificially create constraints to support every use case under the sun, its API semantics are able to align very closely to people's expectations.


Hi, it's Jared (the OP)...

Well said. Perhaps my deeper point is that hooks and soon Concurrent Mode force devs to come to terms with the fact that they _don't_ understand React internals (hence my usage of black box) and that their mental models were wrong this whole time (although some might argue still pretty productive).

I also think Crank is SUPER interesting on so many levels. I built a few demos with it and am fairly impressed. However, practically speaking (and I'm putting my developer relations hat on), I think its generator API is just too intimidating to junior developers.


Isn't the wider problem that people don't try to understand the internals? Some of us may read the code of modules we "require", but experience tells me this is a rarity.

For those that do, this isn't an issue, and for those that don't, this isn't an issue either. Their mental model may be flawed, but as long as the IO is the same, do they really care?

Concurrent mode isn't really a black box. Its just a shortcut to throw away work that would otherwise be invalidated.


I noticed at the end of the blog post you stated that you're very excited about the debut of the upcoming Concurrent Mode (CM) in React. I've read about the problem that Concurrent Mode is working to address; but I'm confused as to why React needs this additional feature set when I'm unaware of any other UI frameworks which have a feature set that seem to mirror that of CM. Vue or Svelte do not seem to need these additional features to achieve comparative rendering benchmark speeds to React, and I'm unaware of any holes in these frameworks that something like CM would adequately address. (?).

Is Concurrent Mode basically a way of addressing performance problems in React, or is this in some way a feature that adds something novel? Or is it just a side effect of an unwillingness to move away from functional programming?

I write React at work, but write Svelte or Vue at home, and I've always found React's abstractions to be the most hard to reason about, and from the looks of it CM will make this more challenging (??). Thanks.


I usually explicitly tell devs to not worry about React internals. Let React decide when to re-render or how to batch state updates. React's API is small, developer time is better spent understanding the API than wondering how React works under the hood.

That said it's still a mental shift. Sometimes I feel like I'm writing React and not writing JavaScript.


Hooks are fine. The approaching ConcurrentMode though is scary. Most of the global state solutions are suffering from various kinds of incompatibility with the concurrent mode that opens the door to various kinds of bugs:

https://github.com/dai-shi/will-this-react-global-state-work...


useMutableSource fixes these concerns. they all will light up green. some have it already as a draft or experimental, for instance zustand: https://github.com/react-spring/zustand/pull/160

with concurrent mode i think of what could be, web applications that can compete against native for the first time. as well as making making components that are resilient to async issues / making async a high level concept. there's a little churn for sure (for library devs, and a specific subset), but imo completely worth it.


> with concurrent mode i think of what could be, web applications that can compete against native for the first time

Native apps feel better than web apps because they have robust UI libraries that web apps do not. React concurrent mode will have zero effect on that.

If the argument is "React concurrent mode will make web apps faster so that they feel more native", my response would be to use something like Svelte, which is available today and is considerably faster than React. React is slow.

Concurrent mode may make React faster but it'll just be making up for React's past mistakes, not the web's.


If you have an application that renders more items than Svelte can handle (not many, we're in the web, you have 15ms max per frame, on a single thread), it will simply keel over and die. Scheduling is natural in native systems, you have occlusion, prioritization and threading of course. Svelte has no means whatsoever to counter load.

With what React is attempting currently your app will render as much as it possibly can while maintaining stable 60fps, the rest gets deferred while it can differ between lesser and higher-priority updates. If you doubt how important scheduling is, look at practically any feasible list component, they're all virtualized. With React every aspect and corner of the application is like that. In theory it could outperform native apps.

Btw, there are countless of robust desktop apps being made with HTML: VSC, Whatsapp, Skype, Spotify, Notion, Hyper, Discord, Slack, ... thought most of them will still feel sluggish compared to a native counterpart. React will change that.


> countless of robust desktop apps being made with HTML: VSC, Whatsapp, Skype, Spotify, Notion, Hyper, Discord, Slack

VSC: chokes on files larger than several mb Slack: eats all of your memory, often hangs and just whites-out while I figure out what to do. Skype: has this app ever actually been good? Spotify: not sure I'd call it robust, but it's functional...enough.

> In theory it could outperform native apps....thought most of them will still feel sluggish compared to a native counterpart. React will change that.

My understanding is that native apps hook into far lower-level functionality and run with _signficantly_ less overhead. They simply execute faster, and far more directly. I don't see how React and needing to go through react-framework -> JS -> V8 -> etc would possibly compete with that, let alone outstrip them.


These apps all fall flat, which is the point i'm trying to make. They're robust from a design perspective, the tools we have to build UI are good enough, but they can't compete against native. Do you think that using Svelte in any those would make a difference? This is why React is attempting to find a solution.

The problem is essentially the same. Native apps are also conflicted with load, they have better means than we have on the web to deal with it, but it's still low-level and complex to orchestrate, threading for instance. Any one of those means pushes your app into async issuee, race conditions that you need to reconcile. With concurrent mode scheduling is a first class concept, your components won't be subject to race conditions. React maintains 60fps, high-priority content (user input, animations, transitions) can be ran fluidly while lesser priority content gets deferred. It has a good chance of outperforming multithreaded native apps with that model.

This demo illustrates the issue: https://youtu.be/nLF0n9SACd4?t=172 which is universal. You run into this on native platforms as well as on the web.


Half of the "robust" apps you mentioned including the context of performance are neither robust nor performant. On really good hardware.


That is my point. They are robust from a UI perspective, but none them can compete against native due to the slow nature of the dom. This is why React is building a scheduler.


> not many, we're in the web, you have 15ms max per frame, on a single thread

Isn't the likely way forward to move the computationally heavy parts of the app over to web workers and to keep the main thread almost exclusively for UI work?


It's really unfortunate that Web Components are utterly useless. They simply are not components. It's insane.


I am not sure what you mean. Youtube is built on web components. Github is using web components. There are various libraries that can do web components, including Preact, Vue, or Svelte: https://webcomponents.dev/blog/all-the-ways-to-make-a-web-co...


In what way are they not components? They have identity, state, can draw output, and accept user input.

What's your definition of component?


It's funny you mention Mithril, because to me, that was the "minimum level of whiteness" box. I tried react fairly early, and when I did something wrong, it was completely unobvious to figure out by debugging the non-minimized code.

Mithril was sufficiently thin for me to drop into the debugger, say "oh, that's how it works" and fix.

I'll take a look at crank though. I do frontend dev only to make my hobby projects accessible to friends and family, so the less to remember, the better.


>I think hooks aren't really making React more of a black box, but just that it's invalidating a lot of people's incorrect mental models on how React works.

Isn't that exactly the point that the big image on the front page is making? If most people have a mental model of a technology that doesn't match what the company is putting out, it makes very little sense to blame the people who have the 'incorrect' mental model. If it wasn't so widespread, your point would be much stronger. But the fact that the core pieces of react are misunderstood, especially when React publishes documents explaining how all of this is supposed to work and how you're supposed to think about this is an indication that something is wrong with React, not the people who use it.


> If most people have a mental model of a technology that doesn't match what the company is putting out, it makes very little sense to blame the people who have the 'incorrect' mental model.

While you're right that we shouldn't "blame the people", I think blaming the company / library in this case doesn't fly either, given the specifics.

The "incorrect mental model" people have about React is based on two things:

1. the prevalence of OO concepts in programming education and in practice in most engineering teams

2. the introduction of class abstractions onto JS prototypes by the ES spec.

followed by:

3. React bundling things like `createReactClass` and encouraging class abstractions in their docs in the pre-hooks days

While the 3rd point above may have been a mistake on the part of the React team, I do think points 1 & 2 are much bigger factors here.

> something is wrong with React

The only thing "wrong" with modern React is that they're challenging the status quo in popular programming concepts with something they believe is a conceptual improvement.

You can disagree with them on whether it represents a true improvement, but saying they're "wrong" because their conceptual model is a departure from the status quo is pretty reductive.


> 1. the prevalence of OO concepts in programming education and in practice in most engineering teams

What makes this point tricky is that React did initially introduce their library with OO concepts for years.


Yup; mentioned that as point 3.

To put that in context: that was at the time ES was starting to introduce OO abstractions to the spec. and it was somewhat trendy to go in that direction. I never got the impression that the React guys were heavily invested in that paradigm, and they definitely moved away from it very quickly after first encouraging it in their API. Everyone makes mistakes.

As a side-note: I think class abstractions in ES are a feature that in retrospect is less of a great idea now than it may have seemed at the time. ES class abstractions obscure their own subtle issues (in a very similar way to the article's fake Twitter screenshot jokes about React hooks).


From my perspective, the sequence was:

- From 2008-2014, _everyone_ was writing their own "class-like" abstractions (see: Backbone, Class.js, five million other "inheritance" libs). So, the React team wrote `createClass` as their own implementation.

- When ES6 classes came out, the React team took that as an opportunity to drop maintaining their own abstraction and switch to something that was actually standardized, and reduce the amount of magic behavior (auto-binding, mixins, etc).

- Function components came out in React 0.14, and were initially limited to just rendering based on props - no state or effects possible

- Hooks now give function components the ability to have state and effects. In addition, encouraging a move away from classes dovetails into the React team's long-term plans for the React APIs.


Yeah, great rundown.

The class abstractions added to ES spec. didn't happen in a vacuum; it was very much on the back of community demand. Backbone especially had an outsized influence.

Perhaps that was a necessary step toward realising tools to solve problems without those abstractions, I don't know.


Perhaps React is just as complex as it needs to be solve the problems it tries to solve. Is that a true statement? Probably not. Close to true? Maybe.

Whatever the case, just because we wish solutions to those problems were easier to understand doesn't mean reality owes us that. I suspect React in particular, being in the web dev space, has a lot of people working with it who have very little CS background. Because they don't understand how React works under the hood or even above the hood is "something wrong with React"? I'm not sure I buy it.

I've seen a lot of really poor React code that breaks all kinds of best practices, many of them explicitly laid out in the docs. Even before hooks came along. In fact it's been hard to find examples of people who understand the dom well, much less React. I will continue to suspect there's something wrong with most of the people using React, not React itself, which from my perspective has only become better over time.


  > has a lot of people working with it who have very little CS background
This and so much this. This applies to "frontend development" in general. I work as a contractor in the frontend space (Europe, no where near FAANG like companies) and very often I meet other "devs" that have basically become frontend "engineers" out of being a webdesigner - like you know, creating nice html templates for wordpress, having decent CSS and photoshop skills and later in their career started to copy-paste some jquery plugins into their template to get nice animated toggles and alike. It is very common in "frontend teams" that people started to get into JS out of webdesign, and have never actually programmed in any other language.

Another issue is even with people with a CS or another STEM background, they only get taught in the "traditional" OOP sphere on top of blocking thread environments. Those usually have a hard time wrapping their heads around higher order functions or async-based development (and to be fair, I also had a hard time when I first encountered it).


Most rank-and-file development doesn't need async and HOF. If your framework does, it's either screwed up or for a special/rare niche. I've been in these debates many times, and when examples are given I can usually trace the "fault" down to the framework or limits of the language. I stand behind this claim.


> I've been in these debates many times, and when examples are given I can usually trace the "fault" down to the framework or limits of the language.

I don't disagree, but my follow-up question with that statement is "ok, now what?"

If you've got a weak/inexperienced developer who's stuck in a framework where they have have to start grokking async/HOF/whatever to solve the problem they've encountered, where do they go from there? It's fine and good to blame the framework they're operating in to be shitty, but they a) didn't have the skills initially to make a solid decision about the framework to use, and b) are now likely stuck with it (unless they're going to do a rewrite with something else).


I agree that our current tooling requires more "rocket science" than it should to do ordinary things. I'm not sure how to fix the entire industry, but the first step to solving a problem is admit there is one.

Early cars were hard to learn, drive, and maintain. Over time they got better via trial and error by manufacturers. The desktop IDE's of the early 90's were like this, but got better over time (until web ruined their market). However, the web is still stuck in 1903: simple things are esoteric. Perhaps because too many other things about "cars" keep changing? Something is wrong. CRUD web dev is a mess.


At least in browser-world, most APIs (i mean the ones defined by the web standards) are built around async/Promise/callbacks/HOF, like it or not. There is no switching to other languages/framework when targeting the browser as a runtime.


This is largely because JavaScript has weak areas.


Crikey. Higher order functions are rare or niche?

To my mind they are oftentimes magic pixie dust that can turn a hideous, verbose and inflexible API into something humane and readable.


Not quite what I said. I said they are not needed for rank and file application (domain-centric) development, IF the tooling and programming language are decent.

If you bring up a scenario, I can probably poke holes in it. Done it many times in many debates. I don't mean to sound arrogant, but I keep winning THIS one for whatever reason.


Most software engineers without a strong background in physics or CFD won't be able to reliably explain how an airfoil works either. Having a wrong mental model (equal transit time of air molecules resulting in lift) does not mean airplanes are not useful.


The question is not whether your mental model is incorrect, but whether the deficiencies in your model cause problematic consequences. For example if my model of how wings work is that "the slower you go the more lift you get", should I pilot a plane I'd probably end up getting in trouble.


See nearby for my early-car analogy.


After using hyperscript via Mithril, I don't think I can go back to writing JSX. Hyperscript should be the defacto way to template HTML in JavaScript in my opinion, it's just so much cleaner and readable.


To me Reagent is the ultimate answer to the markup/code mix. A single language, ClojureScript. Nothing is done in strings except text. I absolutely love it, but haven't been able to use on a production project yet.

[0] https://github.com/reagent-project/reagent#examples


I really like clojurescript in theory, but have a dumb practical reason for not being able to use it. I do a lot of programming in common lisp, and am way too used to a lisp-2.

I literally can't write more than 100 lines of clojure without accidentally shadowing a function binding with a variable binding. I think the only way to break the habit would be to abstain from common lisp for 6 months or longer.


I have the opposite issue trying to write in emacs-lisp after doing lots of clojure. I try to:

  (mapcar my-func my-list) 
and it throws void-variable and then I remember that I have to add the #' reader macro to have it read as a function not a variable.

  (mapcar #'my-func my-list)
It just takes some time to switch the mental model over each time. Clojure did get me in the habit of using unique names for all functions and values because accidentally shadowing a function binding is that more difficult mistake to debug.

In practice I haven't missed the flexibility of a lisp-2, if anything it's just made my code more readable because my names are forced to be more descriptive


the bummer about reagent is that it allocates so many immutable data structures on render. I've not figured out a way to ergonomically write hiccup without paying this constant performance tax, which is felt on a lot of large reagent apps.


using hiccup to write html has been a godsend. I find it much easier to visualize the html that hiccup will generate vs JSX, and I can do arbitrary manipulations on it just like I can with any other clojure data structure.


> I find it much easier to visualize the html that hiccup will generate vs JSX,

Can you elaborate on this? On first glance it seems the same, just with a syntax that uses different symbols than HTML?


It's been the way Elm describes its components; and I believe Andre Staltz has been criticizing jsx in favor of hyperscript since forever [0], and included hyperscript in cycle.js.

Lit-html, which is using template literals, is another good option.

[0] - https://staltz.com/some-problems-with-react-redux.html


I love Mithril but I find hs to be noisy to read and tedious to write.

It's probably because I've been reading and writing HTML for +20 years though.


(mithril author here)

hyperscript is about as close to a middle ground as we can get. It's compatible with JSX for the folks that really really want to see angled brackets, while still being uniform javascript like other API variations (div(), html`<div></div>`, etc). The lit-html syntax is not bad either, but template strings did not have as widespread support back when mithril originally came out.


Is there a roadmap for mithril? As in, what are the current pain points, where development is headed, etc.


I've given stewardship of the project to the community. At this point, it's largely in maintenance mode. Most changes are tightening up loose semantics and the like. IIRC the last major was only a major by technicalities; it didn't really break anyone unless they were relying in weird obscure behaviors.

Since the framework isn't interested in chasing trends and since it provides extension points via lifecycle methods, there's really nothing novel that needs to come from the framework itself.

I know some of the more popular frameworks make it seem that webdev is constantly in churn/evolving, but if you look at React for example, other than the hooks paradigm shift etc, it hasn't really changed all that much in scope over the years either (the same can be said about other libraries as well).

For example, Mithril could easily be used w/ coffeescript when that was still a thing, and people use it with typescript these days too without much fuss since TS is also a project that decouples well. And this is with zero changes to the framework. You can integrate dragula or plupload or google maps or whatever via lifecycle methods as you always could too.

So, TL;DR: I think the focus still remains on making it as stable and robust as possible


Does mithril provides typescript function signatures for its API?



This was helpful. Thanks!


Yeah but why isn't it just HTML?


Why isn't what just HTML?


Yes, probably. I started using haml (then slim) a very long time ago and the hyperscript / elm type syntax is fairly intuitive to me.


What is the point of templating HTML? I really don't understand it. Just write HTML or HTML-like APIs like JSX. Is there some theoretical reason why this is wrong?


Subjective I guess. For me it’s just a reduction in noise and I prefer to read code with significant white space. Perfectly ok writing HTML, but given the option, and if it doesn’t screw with others, I prefer not too.


JSX is HTML templating


I've done a few projects in mithril, and having used both jsx and hyperscript, I tend to lean jsx.

That comes with some very real downsides - mostly getting jsx to work requires a bunch of extra (ugly) tooling. On the other hand, very complex components look very clean.

Hyperscript when you have a relatively nested dom element gets quite messy and hard to visually parse for me.


Back when jsx was introduced people said so too but they weren't as loud as the other group. When you look at a completely new language, reasonml where they're still of the mindset that jsx bring familiarity it makes nosense. Just an excuse for some abitrary preference.


Someone might find these issues interesting on flutter regarding jsx:

https://github.com/flutter/flutter/issues/11609

https://github.com/flutter/flutter/issues/15922


I remember getting excited learning that I could do Xamarin Form in plain function calls in F#. Android is going similar journey simplify UI programming with Jetpack Compose. Jsx is backward and purely stylistic.


Combined with coffeescript it's even nicer since you can ditch the parentheses and have a very clean indented syntax.


As with every issue around javascript front end library, the solution is of course... a new javascript front end library.

- jQuery - Backbone - Ember - React - ???


The only two that I'd put on the same level are jQuery and React. And people are still happily using jQuery to this day (maybe happy is the wrong word). So I don't think React is going anywhere for a long time but if something better comes out then why is that a bad thing?


It is more about the relative instability of Javascript as a platform versus nearly any other platform out there.

Skills I learned in college about writing SQL are still relevant today, several decades later. Skills I learned coding for iOS (even Swift!) years ago are still relevant today. CSS and HTML skills I learned decades ago are still relevant, etc etc. Python/ Django knowledge from 10 years ago is still largely relevant. React/ jQuery/ EmberJS/ Vue/ Angular/ Grunt/ Gulp/ Webpack/ Underscore/ CoffeeScript/ etc... damned near every Javascript library I've ever worked on has an extremely limited lifespan in terms of relevance. Even within React, it's hard to keep relevant. Class based React? We're doing Hooks now!

> why is that a bad thing?

It's only bad if you have to try and maintain 10 year old Javascript and in order to do it, you have to learn a whole new paradigm. IMO it's doubly bad right now since so many people are abandoning semantic HTML and more or less rolling everything as their own custom components.


Not exactly the case for protects like Crank built in the JSX "paradigm".


Vue (solving for not not enough batteries included / ecosystem fragmentation)


To be fair React is now seven years old. So even in the unlikely event that it’s going to be replaced by something else, the old cliche that the JS ecosystem is always churning too fast seems a bit overblown. It’s on track to be the dominant tool for the best part of a decade.


> It’s on track to be the dominant tool for the best part of a decade.

My post was in response to a suggestion that the fix for all the React issues was in fact replacing React entirely.


MooTools!


javascript /s/java/churn


I love the way crank is using generators to get rid of the react complexity.... Did not know about crank, thanks for the link.


For something even more "clear box" (it's not even a framework) that you can understand in a single sitting, check out Meiosis:

https://meiosis.js.org/


Crank looks super cool, thanks for sharing. Using generators for stateful components makes a lot of sense.


I took a quick look at the docs and I'd say the API looks to be pretty similar to mithril.js. Not sure why you think mithril would have a thicker abstraction in comparison.


I feel similarly with Nomad vs Kubernetes


Crank looks interesting, thank you! I was going to try solidjs[1] (which feels pretty close to crank) in my next project, will look more into crank first.

[1] https://github.com/ryansolid/solid


I cant understand how a developer can be aware of existence of Svelte (https://svelte.dev/) and still have React problems.

Just start with creating web components in Svelte, include them in existing React code, and slowly phase out slow, and old tech that React is. This is just frontend lib, why are people so religious about this. You still use Node, JS/TS, etc.

Im I troll? Don't know, but that is just what I did year ago. Now I just laugh when I see articles like this, buy I also feel sad for small entrepreneurs that have to pay big $ for code in "dated tech" - thinking "they are on the edge".


Svelte is be recommended left and right as the "solution to React" but I think it's still way too young of a project to be the cure-all that people think it is.

It's promising, especially for smaller projects/MVPs, but I still have no idea how well it will scale with app size/team size (and have yet to see good evidence that it does it well).

I just find it ironic that people dog on React for being the "default", but then also can't recommend Svelte fast enough, seemingly because its just "not React".


Svelte is so pleasurable to work with. I'm still a beginner but making my own components that can interact with dom elements (for things like three.js/d3.js/peaks.js) was clear from the documentation almost immediately. I'm in the process of reworking some static sites with Svelte because I can re-use the components I make everywhere and the build pipeline is so simple.


We just tried Svelte in a small project at work, and it was a pleasant experience. Like its small api footprint and closeness to plain html/js and its small bundle size.

In our setup with parcel we didn't get good error messages and line numbers (it spit up internal compiler errors), but it might have to do with our setup. Trying it at home with snowpack it gave comprehensible error messages.


React's big enough that large dev orgs have made big investments into it and can't switch to Svelte on a dime.


It's not only that, but there's always dragons in scaling a framework to accommodate teams of hundreds of devs and supporting millions of users. Svelte is less known in this regard. Marginally better along one or two dimensions is not enough to justify the risk.


I'm interested in this - do you recommend any documentation or writing on mixing React and Svelte codebases?


Omg, a promise based render chain? I'm in love.


is this a thinly veiled ad?


Good old XKCD 927 applies [1].

"This system is hard to work with" -> {Abstraction created} -> {Abstracted extended to support new features} -> GOTO 10

Now you have n+1 systems to learn & reason through.

[1] https://xkcd.com/927/


This was my thought as I counted 9+ React alternatives mention in this thread alone.


This is the stuff I've counted so far (I know they are not all React alternatives): Preact, Mithril, Crank.js, Hyperscript, Reagent, Closurescript, Elm, Cycle.js, Lit-html, Haml, Slim, Jsx, Meiosis, Svelte, Formik, Vue...


This is the kind of post that suffers from lack of specific examples. I would love to see an interesting discussion of how hooks are not in line with most developers mental model of React and what problems it's causing (if that is indeed true, or at least true in the eyes of the author). But this post is far too generic to illuminate what the real problems are or convince me that there are any.


Although the article is too generic, or not detailed enough regarding examples of what he states, I have to agree with what he is trying to say. React hooks are a mess, or at least code based around it tends to be. We have had our share of hooks based applications and they've become unmaintainable when reaching a certain size and I am glad that we are back to class based components wherever we can. In may opinion this comes down to the fact - as he states - that the mental model (what will happen, when I do this) is not simple to grasp, thus not predictable for many people.


You realize you've just done exactly what the parent complained about right?

- said it was bad

- not provided any concrete details

> they've become unmaintainable when reaching a certain size

How?

Did you start getting lot of hard to replicate bugs?

Did you find authoring new components was made difficult by your heavy use of custom hooks that were actually not as generic as you thought when you wrote them?

Did you find 3rd-party hooks had bugs?

Did you find that useRef doesn't work like you think it does, and you can't mix and match useRef and useEffect? (ouch)

What kind components are you writing that you find hooks are such a bad fit for?

Be specific.

(I'm not saying hooks are perfect; I've had all of the issues I listed happen to me, but it's still quicker to implement new features on a medium sized web app using hooks than with components in my experience; I work on 3 apps, and only one of them still uses components, and it's the most annoying to make changes too, simply because for simple business components & forms, hooks seem to reduce the amount of boiler plate, and flat out, reduce the lines of code; less code -> faster changes. It's not always that simple (see bugs comment above), but mostly... it is, in my experience: ...HOWEVER, what you've done is just wave your hands vaguely and fail to actually say anything except you don't like hooks)


A mental model being complex to grasp is concrete. Complexity is one of the biggest challenges in software.

One of my favorite papers on it: https://github.com/papers-we-love/papers-we-love/blob/master...


You don't need to understand all the stuff you use.

How complex it is is not relevant unless it has a tangible impact.

eg. I use spark a lot. I don't really deeply understand how the DAG is translated into a distributed computation and the results are aggregated from the cluster.

It calculates things. It's fast. Sometimes I'm surprised by things that are slower than I expect. Oh well. Don't do lots of column renames. /shrug

It's a tradeoff.

Is the effort to understand the detail worth the benefit of doing so? Does not understanding it cause enough pain that it become prohibitive to develop using it?

Is it for spark? No. I really don't care how it's implemented. I don't even know scala. It works fine.

Is it for assembly? No. I don't care at all how my code is JIT'd to assembly / code. It just works.

It it for react hooks? I honestly haven't personally found it to be... but I don't write custom hooks much.

So, your experience with hooks might be different, and you may find the trade-off is more expensive if your case, because it tangibly causes, eg. bugs when you write your code.

...but you are quite wrong if you think that not understanding how something works is a fundamental obstacle to using it.

That is categorically false.

I would argue that it's far from proven that using complex systems necessarily causes the complexity of your system to balloon out of control... or that there is even a strong casual relationship between "mental model being complex to grasp" and the resulting complexity of the system.


  > ...it's far from proven that using complex systems necessarily causes the complexity of your system to balloon...
I don't know what "proven" would actually mean in this context, but there's a notion called "leaky abstraction". It bites you hard when you use a "do-everything" framework and something goes wrong.

All of sudden, the magic stops and you have to deal with a ream of obtuse stack traces, problems that completely smash your metal model of what's going on, and you end up in deep rabbit holes of stuff you don't want to get into at the worst possible time. That is a fundamental obstacle.


All things given, I'd rather use a tool that does not have leaky abstractions and if I need to investigate the inner workings of an abstraction, I can form a mental model of that abstraction with little effort. To your point, you don't need to understand the inner workings of your tools, but being able to quickly learn about the inner workings of the tools is beneficial to creating abstractions, crafting solutions, fixing issues, performing refactoring, tracking the usage of concepts across the codebase, etc.


The mental model of usage is the problem, not the mental model of its internals.


no, its not.

Thats the point: the mental model is irrelevant unless it causes bugs when you use it wrong.

Does it? Does it actually cause bugs?

Not, “in general”; You’re just doing the same thing again here and doing vague hand waving. What actual bugs? What types of bugs?

Be specific

(yes, it does cause bugs, but see how this conversation is pointless when you don’t provide any details? Right, now go read the first post in this thread.)


> React hooks are a mess, or at least code based around it tends to be.

I've read a lot warnings about the pitfalls, and about hooks not doing what you think they are doing, but honestly, I haven't experience any of that, maybe because my use cases are so close to the documented ones, that I don't need to stretch the concept, and it just works as intended for me.

Could it be, that as with many other programming patterns, some developers are using it as a silver bullet, and trying to solve everything with hooks?

Otherwise I'm failing to understand, it would be useful to see examples as the mentioned above.


I am mostly a spectator in this argument, since I'm holding out as long as possible on committing to hooks, but the impression I got from the React Hooks FAQ is that hooks are supposed to be a silver bullet:

> Should I use Hooks, classes, or a mix of both? [0]

> When you’re ready, we’d encourage you to start trying Hooks in new components you write. [snip]

> Do Hooks cover all use cases for classes? [1]

> Our goal is for Hooks to cover all use cases for classes as soon as possible. [snip]

The answer about higher-order components is a little more nuanced but does say hooks should replace most of them:

> Do Hooks replace render props and higher-order components? [2]

> Often, render props and higher-order components render only a single child. We think Hooks are a simpler way to serve this use case. There is still a place for both patterns (for example, a virtual scroller component might have a renderItem prop, or a visual container component might have its own DOM structure). But in most cases, Hooks will be sufficient and can help reduce nesting in your tree.

Learning enough about the React lifecycle to make simple apps was a big task, but it felt like a bounded one for my purposes. Learnings hooks seems... strangely open-ended. There's a small set of built-in hooks that do certain things, and if I need more I'm supposed to build new hooks out of the old ones, and that's supposed to be it. Except that it isn't, because if that's all there was to it, people wouldn't be having difficulty. I just wish the rest of the story was sketched out and bounded for me in some way so I could know what I was getting into.

  [0] https://reactjs.org/docs/hooks-faq.html#should-i-use-hooks-classes-or-a-mix-of-both
  [1] https://reactjs.org/docs/hooks-faq.html#do-hooks-cover-all-use-cases-for-classes
  [2] https://reactjs.org/docs/hooks-faq.html#do-hooks-replace-render-props-and-higher-order-components


> people wouldn't be having difficulty.

I remember people having difficulty with callbacks, then with generators, then with promises, Obersavables... you get the point. There is always something new that tries to make 80% of the cases trivial with a new elegant syntax that hides a lot of complexity, and comes with that 20% of cases where it is harder to grasp.


Hooks are a bit of a double-edged sword in my opinion.

On the one hand, they are nicely composable. You can make one hook call depend on another and you can easily build a lot of cool functionality thanks to this. On the other hand, you are no longer able to directly follow the flow of the code. Making a change to a series of hook calls can sometimes be scary to me as it can be hard to fully understand the cause-and-effect of that change.

On the one hand, you can hide a lot of complexity behind a simple `useSomething()` call, on the other hand the code inside `useSomething()` can be absolute horror, because all the stateful logic is handled through hooks. Any non-obvious use-case ends up being a mess of hook calls. If you only write the code once and never need to touch it again, `useSomething()` can be an amazing hook though. There are some hooks that I have written that I hope I (or anyone else) don't ever have to touch. I might just be a bad programmer though, or missing some obvious patterns.

TLDR: hooks work well, but they have downsides in terms of maintenance burden


On the other end you can compose class components which have lifecycle methods which you need to jump through up and down the code to figure out the full behavior. Which to me is much more unreadable than hooks and effects. Not to mention that lifecycle methods have their own gotchas.


> On the other hand, you are no longer able to directly follow the flow of the code.

Hooks are, at least as they're presented on the surface level, exceptionally functional, so shouldnt it be easier to directly follow the code? Just follow the function calls?


> There are some hooks that I have written that I hope I (or anyone else) don't ever have to touch.

If you need to make such statements something is very wrong. Either your code or with the design patterns you're forced into by your framework/library


My experience has been the exact opposite. Class-based components encourage creating large monolithic classes because it's hard to split class methods into smaller units.

With hooks however, you can create self-contained custom hooks that group all the code of a feature in one separate file. It's much easier to test and to make sense of. It's also easier to make the hook more generic and re-usable when it becomes needed by other components.

I'm definitely not going back to class-based components as I find React hooks a lot easier to manage and maintain.


How is the mental model hard to grasp? Hooks are just functional components. They render information like everything else. Following the same rule set. State change? The hooks renders. Parent renders? The hook renders. Want to stop it from rendering? Use a memo. Want to run logic only when certain state changes? Use an effect.


I’ve had the exact opposite experience. I loathe class components and convert to hooks whenever I can. Class components seem so bloated and enormous with anything but the most simple use cases.

Sometimes when I read these comments I feel like I am using a completely different library.


Way too many articles like this that don't provide examples.

They'll say something and I'm wondering "what do you mean exactly..." but we don't know.

I get how folks might not want to get into the weeds on minutia or etc. But without examples it's hard not to think someone just doesn't 'get it' too.


A trend I've been seeing on HN and Reddit alike are articles that are not in depth, but allow the users of the medium in which they are shared to have a reason to talk about something. This post probably got more attention because it was a dedicated link versus somebody asking HN if they think React is becoming a black box.

I'd much prefer the latter, but it seems that links are the way of websites such as these.


The quality of posts at the top of HN has really tanked over the last 2-3 years. Falling from high quality to “programmer clickbait” like the OP here. It’s a little better if you use /classic as a path, which I understand is only calculated by upvotes from users from the first couple years of HN, before the startup boom. Occasionally /news and /classic are virtually identical making me wonder if there are a lack of active OG users and the algo falls back to default during a lack of classic participation.


Ok, quick test: can you explain in a paragraph why you cannot call a hook inside a for loop?


Because React keeps track of the hooks you are using by the call order, and a loop might indicate than in different rerenders it might have different lengths. You actually can do it, it's just the linter trying to avoid you shooting yourself in the foot.

In fact the linter explains exactly that in a paragraph:

> React Hook "useState" may be executed more than once. Possibly because it is called in a loop. React Hooks must be called in the exact same order in every component render.

https://reactjs.org/docs/hooks-rules.html


That was close :) See my replies below for a counterpoint.


Yes! A hook call occurs at most once per render. For react to figure out which hook call corresponds to what state, it analyzes the call order. Because we write component render functions top down, the hook call order stays the same every time every render. Not so if we call a hook inside a loop [1].

Why would you call a hook inside a loop anyway? Hooks return callbacks and variables, which you can use inside a loop without problem.

[1]: https://reactjs.org/docs/hooks-rules.html#explanation


Just as you don't call this.componentDidUpdate in a loop. I'm reading through the comments and trying to figure out what mental model some have of React that causes them to just don't "get" hooks. I'm starting to think this difference in thinking did not start with hooks.


Hooks aren't always comparable to lifecycle methods. At my company every GraphQL query/mutation has a corresponding hook. There are frequently times when devs are tempted to use them, especially the mutations, in for loops.


So easy I can explain it in a sentence: React hooks must always be called in the same order, and the same amount.

If you push me by asking "why?", I can expand that sentence by including "because each hook call is associated with an index under the hood".

This is probably the only React hook nuance you really have to understand, and it's not particularly difficult.


> This is probably the only React hook nuance you really have to understand

Absolutely not. There is the dependencies array, how it only does a strict equals check (no shallow comparison), how you need to memoize other dependencies so they don't change on every render, why it is a problem to leave it empty, why useEffect cannot strictly replace componentDidMount, why you can't put one hook inside the other, how (and which) hooks can trigger a re-render or block updates, how state is captured by the closure and what to do if you need current state, how to persist things across renders using useRef.. and probably more.


Most of these are also true pre-hooks, it just wasn’t as clear that they were actual concerns and most users ignored them, leading to horribly slow but still functional code. Hooks drive you to more correct usage but the consequences of misuse become more severe.


> There is the dependencies array, how it only does a strict equals check (no shallow comparison), how you need to memoize other dependencies so they don't change on every render

So basic memoisation?

> why you can't put one hook inside the other

Hooks inside other functions may be called at any time, how is React to know which component is calling them?


> So basic memoisation?

No. Before you just had to worry about shouldComponentUpdate and data received from the 'outside'. With hooks you need to memoize arguments to every function you call within the component - you didn't have to memoize class methods. The concerns and patterns involved are very different.


I personally find these quite easy to comprehend, but I suppose I can see how it might be difficult.

Edit: That was snarky, I apologise.


Something that I still don't grasp with React: 1. Your render function runs quite often, e.g. on each state change.

2. But it runs a bit differently sometimes: const [a,setA] = useState(1234); Here "a" will have the value 1234 on the first run (what is a first run? When react instantiates this component? When it mounts?) Then this same line of code will assign a different value to this same variable, because setA was called in the past. Why? How does it know that this exact local variable needs a different value?


Short, potentially inaccurate:

Render functions are only called when a component is being rendered. React keeps track of which component is currently being rendered. When you call `useState`, React knows which component is currently being rendered and keeps track behind the scenes which state that component has.

The way it knows which value it should return for `a` ties directly in with why you need to call `useState` calls in the same order -- React basically keeps a list of the state behind the scenes, and returns the (secret behind the scenes) state in order. If you change around the order of `useState` calls, it can't use the ordering of the calls to determine which state needs to be returned.


and what happens if I unmount and remount it? something like:

<div> {isLoggedIn ? <LogoutButton /> : abcd } </div>

and I change the value of isLoggedIn. Does the state reset? I'm not asking for a solution, just pointing out that even a 'simple' hook like useState has its small quirks.


It does reset, because toggling that flag will unmount the old instance of the component, and then mount a new instance.

This is the same behavior as has always existed with class components and `this.setState()`. Component-scoped state only exists as long as that specific instance of the component is mounted.


1. When React mounts your component, it creates an object to contain its internal state, including the state of all hooks.

2. Before calling your render function, it stores a reference to that object in a private, global variable. (Global in the sense that there's only one per JS VM) (Javascript is single-threaded so this is perfectly safe to do).

3. Each of the built-in hooks has access to that variable, and use it to increment a number representing the current hook index and then store information in an array at the current index.

4. The next time your component is rendered, that information is still there and the hooks can retrieve it.

5. Also some hooks like useEffect set up functions to be called by react later.


This would make for an interesting exercise.

  const React = /* Implement this */
  
  function HelloComponent(){
    const [myNumber, setMyNumber] = React.useState(0);
    // Simulate rendering data to a screen
    console.log("My number:", myNumber);
    // Simulate rendering a clickable button
    const click = ()=> setMyNumber((num)=> num + 1);
    return click; 
  }
  
  React.mount(HelloComponent); // prints 0
  React.simulateClick(HelloComponent); // prints 1
  React.simulateClick(HelloComponent); // prints 2
  React.simulateClick(HelloComponent); // prints 3
General idea being that the React item may be stateful, but the HelloComponent must be a stateless pure function. How can it draw on React's statefulness, while only using that useState() call?

I am working through this exercise now, but I'm already finding myself doing some pretty hacky things to make this work (like finding out who called a function using arguments.callee.caller.name). Still, it's pretty interesting.

Edit: My solution to this: https://gist.github.com/rashkov/f765917d09ebd629f385c21195f4...


Checking the function's caller breaks the composability of hooks: it stops hooks from being called by other hooks. (Also, it doesn't work in strict mode, which is enforced when you use ES modules.) React is the only thing that calls component functions, so React can just remember what component is being called before it calls it. I've posted a reply on your gist with an example that addresses this.


Very cool! appreciate the response, very interesting to see an improved solution on this.

I was mainly interested in solving for how React lines up the useState calls with the actual data that it's keeping under the hood. So I definitely cheesed through the parts touching on how React keeps track of the component tree. I'm enjoying reading through your interpretation of this though. Thanks


Which means you can call it inside a for loop if you have guarantees that the order will always be the same. These are the caveats that don't fit in one paragraph. Also, repeating the rule 'it has to be called in the same order' is not explaining how it works.


What makes the fact that each hook call needs to be associated with an index so unacceptable?


You could say each call corresponds to a timestamp and they need to be ordered, and the person receiving that information would be none the wiser. It just doesn't lead you to understand what's happening underneath. Some may be fine with stopping at that level of understanding, but the stack-based approach of hooks is quite unnatural for JS and I don't think it is good in the long-term for developers to just 'accept' that as supernatural.


So in order to understand not only the basics of the rule, but also the underlying implementation and exactly in what way it would crash, it may require more than a paragraph. I'll concede that. But this is common in programming. As an example, you'd probably spend some time understanding exactly why it is you can't free a pointer twice in C.

There's nothing stopping someone from reading the explanation in the React docs[0] if they want to understand.

[0] https://reactjs.org/docs/hooks-rules.html#explanation


I can give example. Svelte has actions (here details https://svelte.dev/tutorial/actions). You can take pannable action as a starting point from that page. Now try to write React hook that does the same as pannable Svelte action. You can do it. There are "problems" however:

1) React solution will need a little bit more lines;

2) There are multiple ways to write that and some ways are less efficient than others;

3) React solution is harder to write if you only started with hooks.

I'm going to use React because:

1) I don't need to learn anything new (only hooks) to do what I need;

2) I have richer environment: typescript, testing libraries and all React libraries/solutions I might need. Svelte is getting better and potentially it already covers things I need but that was not the case one year ago.


Agreed.

In fact, it smells like the author doesn't know what he's talking about; in my experience "That will break for the following incredibly subtle reasons:" is usually about React fundamentals such as being deliberate with state mutations.

Custom hooks are some of the most useful and fun code to write, in my experience.


I was going to say - the main reason why I like Hooks is because it's a lot simpler to reason with compared to classes, and it makes it easier to avoid whole classes (heh) of bugs.

If anything, React is becoming less of a black box, with a 'simpler' API. It's just that in the process to moving to or learning the new API, people are understanding they didn't actually understand React before. They're now being made to confront that.


> He is the founder of Formik and co-host of The Undefined Podcast.

You can disagree with him fine, but I'm quite sure the founder of Formula knows what he's talking about when it comes to React.


Fwiw, we have a stable admin client that uses Formik. One month, I went to update dependencies. Since the admin client was stable, I only updated its deps for minor versions. Four weeks or so later I get a bug report for that client. Nothing obvious or non-obvious jumped out at me in the component of concern and its blame. After git bisecting, it turns out the minor version bump to Formik had a breaking change.

I've only touched that package a few times since but it never fails to make me wish the original lead hadn't used Formik. I dunno, forms in react have never given me tears, but contrary to Formik's slogan it has been painful, even aside from this versioning fiasco, so I'm not sure this endorsement is as strong as you think it may be.


I'm not endorsing Formik in any way, but I don't think making an accidental breaking change in a minor version is exactly a cardinal sin.

What I'm saying is silly is to say the author is somehow "uninformed" when it comes to React like he's some sort of newbie, as opposed to the guy who wrote the library that a sizable percentage of React apps use for their form components.


Formik started as a class-based library and most likely still uses some under the hood. Maybe he's just not a fan of the hook API and prefers the other way?


> author doesn't know what he's talking about

The author is Jared Palmer. He's a well-known engineer who has worked with React for years, and the author of a very popular OSS React library (Formik).


I think he is a bias against hooks since his library(Formik) doesn't work well with Hooks with react-hook-form coming up to take its throne


Oh, that seems conveivable.

I used Formik long before hooks, then later, after hooks. I remember hesitating a few times because some of the exceedingly neat pattern/syntaxes were impacted negatively by hooks.

I still "happy" with both, but my team is all quite senior and I feel for jnr teams trying to grapple with React AND hooks at the same time.


I think you hit the hammer on the head with this one.


Can confirm that Formik's hooks API is really not very good. Any change to any form component results in the entire form rerendering when hooks are used to connect to Formik context. Lost months of time in last gig to the choice to use Formik.


This is a symptom of a lot of developers thinking they have to write code exactly like everyone else (or at least, strictly adhere to "best practices"). It's a very subtle disease, but I've noticed it again and again over the years.

Reading between the lines, this is a criticism of hooks if they're viewed as a wholesale replacement for classes; from experience I'd argue they're not—they're just a convenient tool for simplifying common patterns. I'd imagine the author knows that to be the case and instead of just using classes where appropriate (or where they wanted), they had to rationalize using hooks because of the aforementioned "but everybody else is using hooks" problem.

I suffered from this behavior for years before I realized it was impeding my work. The term that came to mind for the phenomenon was "The Invisible Developer:" a non-existent developer sitting over your shoulder always judging you for your programming choices. That developer doesn't exist. If instead how "in fashion" your code is is the standard on your team: you're on the wrong team.


That's not a developers fault, that is the insane JS ecosystem. Every year, everything old breaks and everything new is different. Of course no one can keep up, develop intuition and good practices, so all that's left to do is copy. That is how learning works, only the curve never flattens (and nothing is really learned, nothing is gained).


That's just the illusion that's created by the inexperience of most JavaScript developers. You don't have to continually learn the bleeding edge stuff. What they don't tell you (arguably, because it doesn't pay their bills) is that what you should learn is the language. Once you understand that, you can comfortably adapt to any new library/framework/whatchamacallit relatively quickly.

Most of what you've described is just peer pressure. The only reason I know that is that I shared this exact opinion until I said "this is stupid" and started doing things my own way (to much success and peace).


> Once you understand that, you can comfortably adapt to any new library/framework/whatchamacallit relatively quickly.

I disagree. If you know typescript, it's still quite a leap to be able to code with angular, and debug weird stuff where you stare at a blank page, and the back trace in the dev tools include not even a single line of code you wrote.

Also, the language isn't really enough. You need to be familiar with the tooling (npm/yarn, babel, whatever) to use most libraries; so unless you do everything from scratch, you have to deal at least with the churn of the toolchain.


Learning the language is one part, but what enables you to make an application are patterns and paradigms: inflating, mvc, mvvm, immutability, functional. These work for all languages, you learn one once, you can apply it everywhere. It just so happens that maybe every 10-20 years a paradigm replaces another. Since i started writing code in the 90s this happened maybe three times. As far as i am concerned all this ever-changing js fatigue talk is complete rubbish. Even the tooling, we're using the same tools that we used 5 years ago (Webpack, Babel, TS, React, Jest, ...). Microsoft/Apple change their platform toolkits quicker than that!

Class lifecycles being replaced by hooks is a radical but much needed change. Learning it isn't complicated and it will enable you to venture on as everything around you sheds the class based component approach. Swiftui, Vue, Svelte and ofc React are just the beginning.


I get so tired of the churn claim. Let's look over some stuff

ES6 -- 2015

jQuery -- 2006

React -- 2013

React Native -- 2015

Redux -- 2015

VueJS -- 2013

6to5 (now Babel) -- 2015

Webpack -- 2012

ESLint -- 2013

jslint -- 2002

ExpressJS -- 2010

Lodash -- 2012

UnderscoreJS (basically the same API as Lodash) -- 2009

D3 -- 2011

Blockly -- 2012

Node Red -- 2013?? (I'm not sure when IBM first released the project)

Bootstrap -- 2011

PDF.js -- 2011

WinJS -- 2012

SocketIO -- 2012

ThreeJS -- 2010

dotenv -- 2015

momentJS -- 2011

node-sass -- 2012

Winston -- 2014

yargs -- 2011

Modernizr -- 2009

Jasmine -- 2010

Mocha -- 2011

Jest -- 2015

All of these are at least 5 year old and most are 8-9 years old. Look over the most downloaded npm packages and you'll find this to be generally true for all the top packages.


Quite a few of these packages have undergone significant backward-incompatible changes over the years and are intertwined with specific version ranges of other packages. The churn complaints are caused by the cadence of this happening and how difficult it is to stay on a combination of stuff that actually works together. Babel may have been released in 2015 but nothing written back then would work in babel today. Same with webpack. I can't write something and then come back in a year and expect even an ounce of stability in my project. It's good that things keep improving but it's also exhausting having so much time spent performing upgrades and re-learning best practices in tools you were previously comfortable with.


angular.js -- 2010 - 2016

angular -- 2016

That's an example where, when you jumped on the bandwagon at the height of the hype, you were thrown into a backwards incompatible rewrite pretty quickly.

And while npm has been around for quite some time, my outsider impression is that was, for some time, basically discouraged from use, because yarn was so much better.

Compare that to Ruby on Rails -- 2004, Catalyst (Perl) -- 2005, Django (Python) 2003.

Time moves slower in enterprises, with upgrade cycles more on the scale of 3 to 10 years.


Angular 2 shared a name for marketing reasons, but was/is 100% unrelated as every major idea in Angular turned out to be bad.

Yarn solved some npm issues they refused to tackle, but npm got motivated and has now solved most of them. Meanwhile, yarn 2's release has been a disaster and has seemingly resulted in most people (myself included) moving back to npm.

I've done Rails and Django work. Rails in particular took years to migrate to the next version. I'd add that Rails has seen 6 versions in 16 years which gives around 1 major breaking upgrade every 3 years (in truth, there's been about 1 major change per year as point releases are pretty big). Likewise, wikipedia gives almost 20 major django updates (I haven't used it in several years, but point updates used to have a very big risk of breaking the project I was working on).


> Angular 2 shared a name for marketing reasons, but was/is 100% unrelated as every major idea in Angular turned out to be bad.

Be that as it may, Angular 2 meant nobody was willing to commit to any fixed time span to support Angular.js, so it basically forced everybody to migrate off of Angular.js, introducing the toil and churn we were discussing.


>Every year, everything old breaks and everything new is different.

It's great for online educators and others who monetize devs though..

The JS ecosystem almost seems like it's self promotional, where the monetization opportunities result in a higher self marketing activity of individuals on platforms like Twitter, which of course builds up hype and draws more people into it.


Nothing old broke with the introduction of hooks.


This is true, but even as a fan of hooks, I must admit that you'd be fighting a losing battle if you tried to convince your coworkers to merge your PRs with classes in them, in most places.


That is a problem with your coworkers, certainly.


There is a real pressure from the ecosystem though. When looking for a library there is good chance that anything recent is written with hooks in mind, and the examples are primarily hook based and the issue tracker is full of questions about hooks... so while you can try to alter your own behavior it feels like you're swimming against the tide.


See my reply to _stefan above (responding to the need to use something out of necessity for lack of alternative).

In respect to swimming against the tide, this is where experience comes in and knowing both how and _why_ something works the way it does. Over time, you can develop your own opinions and not have to worry that much about what everyone else is up to.

Admittedly because I mostly work alone that's a privileged POV of sorts, but I think teams can "act as an individual" and adopt a similar attitude (scale of team permitting).


I'm an Android developer who despises Kotlin, reactive programming, and "the Google way" in general. My main gripe with all this is that it needlessly complicates everything that can already be done in Java with vanilla SDK. All these additions are touted as a way to write fewer code and do it faster, but the problem is, it's all rather complex under the hood and requires you to hold a lot of context in your head at all times. And if you want to read someone else's code, you gotta have the encyclopedic knowledge of Kotlin, because characters are apparently a dollar each and it's not like we can spare some to write code with actual words people can search for. And to make it even worse, "the Google way" is a moving target. It's constantly evolving just for the sake of change.

In the end, I'm sticking with Java and vanilla SDK because it just works and only changes ever so slightly with each major OS release. Also my apps run pretty darn fast on 7-year-old devices because they only use the CPU to do useful work.


I find Kotlin more readable than Java in most cases -- less noise to drown out the actual logic. Could you provide an example of a language feature which requires you to "hold context in your head"? It's possible that you have just worked in bad codebases abusing Kotlin sugar. Inferred types for example can improve readability, but only if the variables are named appropriately.


> Could you provide an example of a language feature which requires you to "hold context in your head"?

Extensions. Basically every project has its own dialect of Kotlin that you have to know everything about if you're to understand anything. And good luck doing that without an IDE.

> It's possible that you have just worked in bad codebases abusing Kotlin sugar.

I've never actually worked with Kotlin, I've just seen many examples of it. The problem is, the language itself pushes the developer to use all the sugar, and they have to control that themselves. As opposed to Java, where writing unreadable code would take extra effort because of how dumb and simple the language itself is.

Also, to me it feels like an abstraction on top of Java that gets in my way as opposed to being helpful.

I love dumb programming languages.


Good example, React is to web what Kotlin Android is to Android, over complicated and bloatware.


Exactly. I wrote this in another comment but I've been following a Github issue about hook support in Flutter, and I understood React hooks much better after reading that than I ever did before. It is clear now what exactly the problems hooks solve are, composable life-cycle state reuse. I think that because most people don't really understand why hooks were even needed, they can't wrap their minds around them.

https://github.com/flutter/flutter/issues/51752


I, for one, do not mind developers adhering to some common patterns/best practices. Whenever I open a codebase foreign to me, I bank on those patterns to understand the app to be able to contribute, learn, etc. Seeing new patterns would be helpful to myself, of course. But, there's a good chance I would bail out if I don't have a huge need learning that codebase.


Hooks do draw you in the direction of a wholesale replacement just because of their incompatibility with classes. I wouldn't consider that to be a bad thing but it does take some time to adjust to the change at first.


Well, code reviewers can choose to enforce best practices, so you kind of do have to write code in a certain way according to them.


Hooks are both a blessing and a curse.

The most telling difference after starting to use hooks when working with both junior developers and more seasoned ones is that code that seemingly (and intuitively) behaves in one way actually does something slightly different, or worst case - something entirely different. Most often the culprit is a combination of the hooks themselves, the rules and the more general issue of the dependency array and lack of built-in immutability in the language.

This happened before hooks as well, but the class syntax and lifecycle methods felt like a thinner layer on top of JavaScript. Hooks is a much more proprietary concept that tries to solve a much wider problem - having stateful functions, except they make no sense outside the realm of react as they exist right now. Maybe some form of implementation using generators would bring it closer to the language, but that would most likely introduce it’s own set of challenges.

Don’t get me wrong - I enjoy working with hooks, but it just doesn’t feel quite right that they are so tied to some «magical» implementation that requires a large set of rules to behave as expected. It helps to look into the implementation, and especially to reimplement a simple version of react with hooks yourself - but that’s just not a realistic option for many.

Kudos to all the innovation coming from the React team and community though - I’m sure they think about this stuff all the time.


Well said. I like the idea of generators if possible, but have no idea if it actually is possible.

> they are so tied to some «magical» implementation that requires a large set of rules to behave as expected 100% agree here & with your sentiment about the Class API


I tried this, and it's possible using a monadic interface. Just like replacing promise.then with async await you can replace monad.flatmap with generator yields. But I've already seen this concept discussed by the react team and it seemed they didn't like it.

What's cool with a monadic interface is that you can create lots of other interesting things, as long as you adhere to the interface. For instance, I think it's possible to achieve something similar to async render functions without specific support for it.


> Maybe some form of implementation using generators would bring it closer to the language

That's what https://crank.js.org does. I haven't tried building a real app on it yet, but I have to say it does seem pretty elegant and promising at a first glance.


Thanks for the idea. I've formulated a small version of this problem as follows, and provided a solution elsewhere in this thread:

  const React = /* Implement this */;

  function HelloComponent(){
    const [myNumber, setMyNumber] = React.useState(0);
    // Simulate rendering data to a screen
    console.log("My number:", myNumber);
    // Simulate rendering a clickable button
    const click = ()=> setMyNumber((num)=> num + 1);
    return click; 
  }

  React.mount(HelloComponent); // prints 0
  React.simulateClick(HelloComponent); // prints 1
  React.simulateClick(HelloComponent); // prints 2
  React.simulateClick(HelloComponent); // prints 3


this is a pointless example. it doesn't render anything, and therefore doesn't have to deal with React's render cycle.

also, you shouldn't use useState unless you want it to rerender, which you don't because you're printing to console. use a ref instead for myNumber.

the problem you are trying to solve, updating a number if someone clicks on something, is already solved in React:

    const HelloComponent => React.forwardRef((props, forwardRef) => {
     const myNumber = useRef(0)
     const printToConsole = () => {
        myNumber.current = myNumber.current + 1
        console.log("My Number:", myNumber.current)
      }
      render (
        <div ref={forwardRef} onClick={printToConsole}>click me</div>
      )
    }
then you can simply trigger a click by calling .click() on the forwarded ref wherever you happen to mount it.


Every time I see one of these posts glorifying class-based components and shitting on hooks, I always come away with the same impression: this person doesn't understand what hooks are for.

There are plenty of examples where a specific interaction might be more 'intuitive' in a class-based component, especially to someone who knows the lifecycle methods well, but class components had a tendency to become very big with lots of instance methods and be responsible for too much.

React has always had an eye towards being pure functional, preferring that you hide your application logic in pure functions, but when you're dealing with complex interactions that rely on various combinations of state and props, there wasn't an easy way to abstract that away. Forget about DRYing out your code base, it was really common to see identical functions in `componentDidMount` and `componentDidUpdate`. Hooks represent a way of removing complex behaviors (that can't be represented as pure functions) from the component altogether.

A lot of people _consume_ hooks, and these are the kinds of usages that people are really complaining about. Components with 3 or 4 or 10 useState, useEffect, etc at the top. These behaviors get copy-pasted all over the app. They are hard to reason about in the same way that code where you never wrote any functions would be hard to reason about.

So yeah, you have to get used to thinking with hooks, just like you have to get used to thinking with pure functions. Sorry you had to learn something new.


Hooks are not pure functions, though, or purely functional. A function that returns different results when called with the same arguments is not pure in any sense. One of my biggest issues with hooks is that they make it difficult to reason about which functions are pure and which are impure. Just because it's using functions doesn't mean it's functional.

See for example this comment [0] from the hooks RFC discussion how they could have been made more functional.

[0]: https://github.com/reactjs/rfcs/pull/68#issuecomment-4331556...


Hooks definitely meet the dictionary definition of the term “functional programming”.

Like Wikipedia states, you’re conflating “functional programming” with “pure functional programming”.

https://en.m.wikipedia.org/wiki/Functional_programming


So is C language a functional programming language?

Definition of functional (from Wikipedia page you linked to): In functional programming, functions are treated as first-class citizens, meaning that they can be bound to names (including local identifiers), passed as arguments, and returned from other functions, just as any other data type can.

In C language you can do all that. But C is not a functional programming language at all. Neither is Hooks functional. Even assembly language has "functions" but it is not a "functional language".


C is a FP language. So are C++, C#, Java and JavaScript.

They're not functional first like F# or Scala.

A programming language can embrace multiple paradigms.


> C is a FP language.

Well then so is assembly language.


Thanks for the clarification! The Wikipedia says they’re often used synonymously, and I’m definitely guilty of conflating the two


Fully agree, it’s so weird to read in many places that hooks are supposed to make react more “pure” while they are actually a way to make functions non-pure. Pure being defined like you do.


> Just because it's using functions doesn't mean it's functional.

I never said it was. I said that hooks are a way of abstracting functionality that can't be easily represented as pure functions.

> they make it difficult to reason about which functions are pure and which are impure.

Hooks have to have 'use' at the start of their name to be recognized by React. It should be instantly obvious which functions are pure and which aren't as long as you don't wrongly namespace your pure functions with 'use'.


Thanks for replying! I did not downvote your comment, and I don’t think it deserves it.

I do disagree with it though.

> hooks are a way of abstracting functionality that can't be easily represented as pure functions.

Yes, this is true, but in what is (IMO) a much less semantically clear manner than classes or a monadic interface. If a HookMonad or something similar were passed into components as an optional argument, I’d have very few complaints about hooks.

> Hooks have to have 'use' at the start of their name to be recognized by React.

Is this architecturally true or just conventionally true? It seems like this would just be determined by what they name the functions, which needs to be enforced by convention, but I suppose JS is dynamic enough that they could actually require the names conform to some standard.

Either way, it doesn’t prevent people from importing them with other names, and even if it did, digging through a large function searching for “use” function calls seems much less obvious than the presence of an optional function parameter or the fact that a component is a class.


fwiw, the author is one of the most well known react devs in the world and definitely knows what hooks are for. he just also has empathy for how it is looking to newer devs.


I don't think it's becoming a black box at all. Classes were more intuitive, sure. But, they really allowed you to write some gnarly and inefficient code. I've always felt that React lets people get away with not fully understanding JS fundamentals. It's very apparent when dealing with some bootcamp devs who never had to write production vanilla JS. One example is that you can get away with not fully understanding that with classes you're dealing with different instances of objects.

Understanding hooks did take effort. Only after I read Dan Abramov's article a few times was I able to write hooks w/ deterministic results. It is a MUST read. Don't let these Medium authors you've never heard of confuse you with their understanding and basic examples. https://overreacted.io/a-complete-guide-to-useeffect/

To me, understanding Hooks feels exactly the same as learning Physics in high school. You not only have to keep track of variable scope in your effect callbacks. You also have to keep track of function iteration. All the variables in your dependency array are like variables in a physics function and as they change so too do the variables you reference in the function scope.


> Understanding hooks did take effort. Only after I read Dan Abramov's article a few times was I able to write hooks w/ deterministic results.

A tool for building web pages that requires that level of effort to learn it is not a good tool.


Having worked on large scale production apps through jQuery days, Knockout, Backbone, Angular 1, and now React, I still think this is the best tool for the job. What do you use?

I don't think spending a few hours to fully grasp an article should be the metric to deter someone from a good tool.



So happy I went down the Vue-route from the beginning. Could I learn and understand hooks really well if I wanted to? Sure. But with Vue lifecycle hooks - and with the upcoming Vue 3 composition API - I don't have to overthink anything. The API is intuitive, readable, and a pleasure to work with.

I'm sure there are counterpoints - Vue doesn't teach the right mental model about component lifecycles, or something to that effect. But I don't care if the Vue abstraction is too simplistic - in fact, that's what I like about it.


React was always a black box, more or less. To me, what happened was the React team decided boilerplate was worse than cognitive load and the appearance of simplicity, and changed the framework accordingly.

Class components are easy to understand and reason about (mostly) - but they result in a lot of boilerplate code for simple functionality and event handling. Hooks, to me, are the opposite. They have all kinds of limitations and footguns which you need to be aware of (yes linters help) but they give the code a much cleaner appearance.

I personally prefer obvious boilerplate over clean aesthetics but I know lots of people who prefer hooks. I've sinced moved to Preact and have not missed real React once.


I'm not sure if I would describe it as boilerplate because it includes very real cognitive overhead. The best example is the lifecycle methods: if you access a prop in componentDidMount you need to remember to handle what happens if that prop changes in componentDidUpdate. It was incredibly easy to write broken components using the class API and much harder with the hook API.


couldn't you just write the same function to handle the prop in both componentDidMount and componentDidUpdate ?


Sure, but you still have to know to do that and to do it correctly by checking whether the relevant values have changed in componentDidUpdate.


I think the problem is not so much with the React architecture, but with the culture of JavaScript, which:

* does a horrific job with documentation

* delivers millions of packages with demo-grade half-finished projects

* has tutorials which show basic functionality, without going into any sort of depth, which people glue together by pattern-matching

That doesn't work well in general, but for something as complex, deep, and, well, architected as React, it doesn't work at all. People really do need to understand reactive programming, functional programming, and deep concepts to handle React well. Resources to do that don't exist.

This is the claim for React's documnetation:

"The React documentation assumes some familiarity with programming in the JavaScript language. You don’t have to be an expert, but it’s harder to learn both React and JavaScript at the same time.

We recommend going through this JavaScript overview to check your knowledge level. It will take you between 30 minutes and an hour but you will feel more confident learning React." source: https://reactjs.org/docs/getting-started.html

Really? Read that again. REALLY? Someone with 30-60 minutes JavaScript programming is expected to code in React?

That's the target audience of most of the docs, and nothing goes far enough to get people qualified to use the tools. It becomes a magical black box. The posts in this thread show this attitude too: "You don’t really need to understand how React works, you just need it to work"


Did you read it again?

"to CHECK your knowledge level"

Doesn't sound at all to me like they're saying "read this and you'll be ready to learn React". More like "if you find any part of this overview to be confusing, you might find React confusing."

Also, I learned enough React to be dangerous when I didn't know anything about reactive or functional programming. I imagine plenty of people have had the same experience.


> People really do need to understand [...] deep concepts to handle React well.

"Handling React well" is subjective. What are you building?

> but for something as complex, deep, and, well, architected as React

I'm not sure what "architected" means in this context. But re: complex and deep -

React is complex to the extent that you need to build complex things. It is deep to the extent the developer requires. This is a great aspect of its composable design - it's just components made of components made of...etc.

But people don't learn React by building huge, complex, deep things. They build simple things, and go from there. In this respect, React does a great job with documentation. They start small.


It's deep and complex in the same way Lisp is deep and complex. Or if you don't know Lisp, a weaker analogy is Go.

I'm a huge fan of React, but without understanding of why it is, people use it wrong all the time.


Pretty much yes. I'm a C++ programmer that barely knows javascript that is using React to build a UI for a product. It's complete magic to me and I have no idea how it works. I haven't seen any deep documentation anywhere that would give me more insight that I have now. shrug


For starters, I'd suggest going through Rodrigo Pombo's walkthrough "Build Your Own React" [0], my post "A (Mostly) Complete Guide to React Rendering Behavior" [1], Dan Abramov's treatise "A Complete Guide to `useEffect`" [2], and Shawn Wang's talk "Getting Closure on Hooks" [3].

I also have additional links on both React's internals [4] and React hooks specifically [5] that should be useful.

[0] https://pomb.us/build-your-own-react/

[1] https://blog.isquaredsoftware.com/2020/05/blogged-answers-a-...

[2] https://overreacted.io/a-complete-guide-to-useeffect/

[3] https://www.swyx.io/speaking/react-hooks/

[4] https://github.com/markerikson/react-redux-links/blob/master...

[5] https://github.com/markerikson/react-redux-links/blob/master...


Is there any other way to save comments in your history besides commenting on them?


I don't think it's just the extension I'm using, but every comment should have a 'favorite' link?


whoa nice. Wasn't expecting that sort of reply! thx.


Sure. If you've got any other specific questions, let me know and I can try to point to some relevant resources.


Too many things in web-ville are becoming black boxes, or at least dark-grey boxes. ORM's, route mappers (with URL beautifiers), most "progressive" UI kits, etc.

This is usually "solved" by hiring technology-specific specialists to focus on each mystery meat layer. The result the same kind of application takes TWICE the resources that it did with simpler tools of the past. (I don't know if they were simpler, they just were a better fit for business CRUD itself, web is not, it originated for static documents.)

"The web" may have simplified deployment (installs & updates), but it complicated everything else. I don't even know that it's either/or, we just need better standards, such as a stateful cross-platform GUI markup language. Businesses don't really need or use mobile-centric UI's for their productivity-oriented applications. Progressive (mobile) UI's are a solution looking for a problem, in the business world.

Some architects say "choice is better", but that choice seems to be costing the business dearly. There may be bias in that complexity and confusion benefits technicians more than businesses. The "mono-culture" IDE's at least got shit done without an army to manage all these "organic" web layers.

We de-evolved. Ooga Booga.


The web has been haphazardly put together over decades by committees and big companies.

Alot of this started as workarounds for the problems with web development and then became monstrosities of their own.


>The result the same kind of application takes TWICE the resources that it did with simpler tools of the past.

what is an example of a simpler tool? .net Winform?


Visual Basic 6, Delphi, PowerBuilder, Paradox, Oracle Forms, etc. They had warts, but generally got better after each release.


VB6 is terrible. I much prefer the current front end landscape rather than that

"Dim it up!"


For who? Its bad points were mostly fixable. MS just stopped working on it an threw out it.


correction: "and threw it out" (replacing it with Dot-Net, which wasn't backward compatible.)


for everyone.. terrible IDE that is more suited for simple scripting, than the complex client logic that exist in today's webapps.

Terrible language. End Sub as opposed to curly braces? Really?


Example "complex client logic" that we can analyze here?

As far as programming language syntax preferences, that's a different subject, and largely subjective.


Did someone say Laravel?!


Majority of freelancers and web shops will evaporate if it breaks. Laravel is like Mecca for junior devs. Last I used it was in 2014 tho, not sure how more of a black box it is now.


Maybe I am being naive, but I'm just not sure what people are building with React that requires such heavy focus on optimization that we're starting to look at Concurrent Mode. Is it an issue with React performance, or are we just asking the client devices to do too much work? React is a UI library after all, how complex does a UI need to be before you run into performance issues, or is it that the UI framework is doing work outside the scope of a UI?

I understand less capable devices is a concern as well, but that just makes me wonder even more why people are building such taxing applications with React.

PS: Please contribute to the conversation, I'm genuinely curious, this isn't my area of expertise. If you're sending a downvote, spend a moment to tell me why I'm wrong.


The fundamental problem with UI frameworks is figuring out what to re-render based on some event, while also providing a declarative view of the code to the developer.

Some libraries optimize this via micro-optimizations (e.g. inferno is carefully crafted so that browsers use the hidden classes optimization nearly all the time). Some libraries do this by compilation (e.g. svelte takes assignment expressions and rewrites them into a reactive trigger call). And so on.

The problem though is that no matter what the framework does, there's no way to render 1 million things in a page all at once (and yes, people do try that). On a fundamental level, doing anything a million times synchronously will block the main thread (javascript is single-threaded, you see).

In the mithril.js community for example, the solution is to say "well, don't render 1 million things, use pagination or occlusion culling or search or some other mechanism since no one's ever going to meaningfully interact w/ 1 million UI elements simultaneously anyways". In the React world, concurrent mode is a technical attempt at addressing that same issue.

There are various different use cases that fall within concurrent mode's scope, e.g. avoid stuttering animations (the mithril.js community answer in this case btw might be "well, use CSS" or "use lifecycle events and vnode.dom to drop down to vanilla JS").

The React team is corporate-sponsored, so they solve problems in very different ways that an OSS project run by volunteers.


AFAIK React itself is performant enough, the bottleneck is client code within components. I suppose the change is mostly for full enterprise web apps at the Facebook level that likely have thousands of components running at the same time. Concurrent mode lets React split up work and give some time back to browsers (for e.g. mouse movements or rendering) to prevent large freezes on rerenders, essentially allowing prioritization of certain interactions for latency. On top of that, I think it also helps to remove some of the bottleneck that comes from I/O.


I wrote a few huge class component-based Apps in React and they were working like charm and were very maintainable even for junior programmers. A few days with Redux and development was as easy as in jQuery days.

Then we hired a few front-ends who started pushing functional components where possible as it became the new paradigm and recommended way of writing React apps. From my perspective there is absolutely no difference between class and functional components, class is a few lines longer and it's supposedly harder to test but I don't know exactly why because testing classes was never an issue.

A few months passed by and maintenance became a headache because suddenly functional component X, Y and Z needed lifecycle methods and those were only available in class components! But class components are bad, right? So let's update React and use newly introduced hooks.

Now instead of me and 2 juniors you need 10 seniors to maintain the apps, nobody knows what does what, it's a nightmare. Class based components and even everything redux-related is much easier to comprehend than small logic in hooks. It's extremely easy to write unmaintainable code with hooks.


Yes, I am experiencing similar issues as well in our codebase. Half of it is class based while the other half is now in hooks. Apparently classes are now "bad" and therefore it should be immediately abandoned. Unfortunately this leaves us with a fractured codebase. The real pain to productivity comes when trying to onboard new developers. They have to now double their learning efforts by having to understand two programming paradigms. It's easy for them to get confused and intimidated. I don't blame them. Even I hit some level of mental fatigue of having to remember how things are done when switching between the two. What I dislike and don't understand is the lack of discipline developers have to stick with an existing library or framework. This desire to constantly hop to the next latest thing — in this case classes to hooks — ends up fracturing the codebase, making it more difficult to understand and manage. For what? A trivial gain in supposed productivity? Perhaps writing the hook itself versus a class is indeed more efficient, but the fracture in the codebase it brings, I believe, ultimately brings a net loss in productivity.

Anecdotally, I am starting to get more used to hooks, but I'd prefer to go back to classes if I had the choice. I found classes are much more explicit on what is going on, especially when trying to understand the various states of render cycles. What's happening in the cycle in hooks is challenging to me. There is also a proclivity to accidentally introduce infinite loops with hooks, which was a rare problem when dealing with classes.


> There is also a proclivity to accidentally introduce infinite loops with hooks, which was a rare problem when dealing with classes.

That makes me quirk an eyebrow. Somebody's doing something fundamentally wrong in how they're writing the component if they're making an infinite loop happen with hooks.


I'll disagree with this a bit.

It was always possible to do this in class components if you had some kind of a `setState()` call in your `componentDidUpdate` method. But, this was a rarer stumbling block.

On the other hand, with hooks:

- Effect hooks always run after render by default unless you specify a deps array to limit how often they re-run

- It's fairly easy to queue a state update that changes one of the values in your deps array, causing the effect hook to immediately run again

So, it's "fundamentally wrong" in that it's a thing you don't _want_ to do, but it _is_ a lot easier to make that mistake now.


If you're using setState in useEffect directly in a component then you're probably doing something wrong. All the valid use cases I can think of for functionality like that should be using a wrapping hook function, rather than re-implementing functionality separately in components.


What does that have to do with being a junior or senior?


The harder it is to reason about the code the more you're selecting for people with greater experience and capacity to decide what needs to change and what the ramifications will be.


I have had a similar experience.


I highly recommend this talk (first half) for a great introduction of how React Hooks work internally, Ryan remakes the basics of hooks from scratch in 30 min:

https://www.youtube.com/watch?v=1jWS7cCuUXw

I agree on 2 of the points of Jared Palmer but disagree on one:

- [agreed] The new "Concurrent Mode" will take things to a new order of complexity. I am actually very afraid of this, it seems like one of the things that might actually kill React, and I love working with React. I like it so much that I've invested into creating few React libraries to make my life easier.

- [agreed] React Hooks are difficult to get started with and to really understand them. IMHO this is mainly due to "React lifecycle", which is just a difficult concept (even with classes!). Life is not easy, and there are some times that there's complexity and you need to learn new complex concepts. No issue here IMHO.

- [disagree] React Hooks is currently magic. While it's a complex piece of software with many small details, once you understand fairly well the lifecycle (and React docs are great at this, and Dan Abramov's https://overreacted.io/ digs a lot deeper for the curious) all bugs are very clear.

I am currently mentoring someone in React who already knew HTML+CSS+JS, my recommendations are: get used to the syntax by practicing, learn the 3-4 typical libraries, and learn very well the lifecycle including how useState's setState and useEffect's dependencies work. That's most of day-to-day React work.


I like hooks and prefer them over class components, but I think this is a problem. Almost every React developer I know has a poor understanding of how hooks work because it's so fundamentally different from what they're used to. In most simple cases (probably 90+% of the time) you can get away with a flawed understanding of hooks; it doesn't typically bite you until you get into trying to write custom hooks with complex logic and/or side effects. Dan Abramov's dissertation on useEffect is a great example of how much complexity is hidden behind what appears at first glance to be a simple function: https://overreacted.io/a-complete-guide-to-useeffect/


Is there anyone who would argue that React Hooks are "intuitive", or at least become that way after you've used them for long enough? Genuinely asking.

I worked with React for several years and I've worked with the web for almost a decade, but when hooks came out I immediately "noped" out of there. Not that I couldn't learn them, but they just felt like a deeply contrived way of managing state changes. I'm comfortable with a functional style for lots of things, but when it comes to your actual core application state, FP has always seemed very out of place to me. It's almost antithetical: FP's whole thing is being stateless! It feels like a square-peg-in-a-round-hole situation.

By contrast, using something like MobX for reactivity combined with as-stateless-as-possible class-based React components (and some totally-stateless functional components!) was extremely easy to reason about and scaled really well for us with almost no boilerplate.

I realize that doing something like concurrent-mode requires some unique accommodations, but I just don't understand the big push for hooks. Do they only exist because of concurrent mode? And if so, was there really no other option for getting the same results?


I agree, I think they took a left turn at Albuquerque trying to get into the state management game and honestly saying this as a person that likes FP for everything but UI components, I prefer objects when it comes to modeling UI's it's the one domain in which it fits without impedance mismatch. The problem is UI has state and state and it's management does not fit well with objects as it tends to be event, time and data dependent.

There are some good solutions to state management that are complimentary to React such as XState and it really should be dealt with as a separate concern from a UI component library.

I am concerned that React's object based approach is going to become a second class citizen in lieu of Hooks and that state management is going to get to hardwired to the UI component library.


Exactly. I'm a big believer that state-as-an-implementation-detail is a code smell, but that if your program is fundamentally concerned with state (as UIs nearly always are), you should equip yourself with tools that let you ergonomically manage that state instead of trying to sweep it under the rug and pretend it doesn't exist. Hooks feel like state-denialism to me.


> and that state management is going to get to hardwired to the UI component library

I don't really see how that's a different state of affairs than class-based components. You just do this if you wanted...

    const [thisState, setState] = useState({});
...and its uses would generally be semantically identical to state-based stuff without hooks.


I believe there are genuinely people who think of hooks as intuitive:

1. Hooks handle a lot more of React's lifecycle in a way that better matches how they're used

2. They allow more widespread usage of functional components. No more rewriting to and from classes while refactoring!

3. Concurrent mode all the things!

Unfortunately, the opposition to hooks has gotten lost in the sea of people trying to wrap their heads around it. It's also really easy to respond to criticism with "Just wait! Cool things are coming!". That's no fun for someone who has legitimate criticism and doesn't really see a way to voice those concerns.

It's a lot of what made me seriously consider other communities. React may be dominant, but gosh, at least I can roughly predict where other projects are going and can contribute in meaningful ways


> Is there anyone who would argue that React Hooks are "intuitive", or at least become that way after you've used them for long enough?

Yes. I've been using React for a while, started with class and functional components very close in time, and almost immediately found functional components with hooks far more intuitive than class components and lifecycle methods.

Of course, I also started programming before the mid-1990s OOP hegemony, and while I did use OOP early on my programming career, I also used lots of other paradigms early on, too. I think for people whose programming knowledge is entirely OOP, Class components and their lifecycle methods are probably more intuitive. Though given that React imposes unusual restrictions on state management in class components, that mean using usual OOP class design doesn't work for class components, I find even that a bit odd. React’s rules attached to hooks seem a lot less uncanny valley to me than React’s rules applied to classes.

IME, hooks get awkward mostly when a component is managing too much unrelated local state—which in a class component (or, really, even a functional one, though one associates this more with OOP) would mean you are flagrantly flouting the SRP. I actually find the friction that hooks provide in that case—which does seem to bite sooner than with class components—a welcome nudge to reassess responsibilities and refactor before the component becomes unmanageable. (And usually that involves moving more state management out of components and into, for the apps I work on, redux.)


I also prefer hooks. They give you the flexibility of mixins with a better composition story. And reusing hooks in my experience is more like a lightweight OOP style, compared to the somewhat clunky FP ceremony of higher order components, as the API makes it feel like I'm passing around instances of little state objects. The refactoring flow is also dead simple. I prototype behavior inline at the top of a render function, then just cut all that out to a reusable hook which I can then choose to move to props or context above the now dumb component, and factor out into smaller hooks as I wish. Slicing the behavioral model of a component up to jam into the class lifecycle methods was painful to me in comparison. The static analysis tooling also finds and allows auto-fixing of scores of dumb mistakes that used to catch me at runtime when using classes or HOCs. My experience with hooks actually got me more interested in learning ReasonML & Elm!


People keep mentioning lifecycle methods, but I very rarely found myself using them. Those, too, were a code smell to me, especially if they caused side-effects in application state. I don't see them as an integral part of the class-component paradigm at all.


If you don't need lifecycle methods in class components, you probably don't need hooks much in functional components, since the most used hooks are direct substitutes for lifecycle methods.


I saw hooks more as a replacement for this.state/setState (or your state management library's equivalent). So if you've got a dropdown that can be either open or closed, for example. Is that not the case?


Well, useState/useDispatch is a substitute for that, useEffect is a substitute for most lifecycle methods, useMemo is a hybrid that is basically useState + useEffect for updates.

IME, useEffect is where the complications tend to arise (assuming you are using a state management library for non-local state, which seems to be the dominant approach even with functional components.)


Sure, I've developed React apps since it first appeared, and hooks I find to be by far the most intuitive API. They work closer to how I understand React to work internally, with minimal boilerplate. The things I find annoying about React were an annoyance before hooks (mainly to do with async). I find the code written with hooks cleaner, easier to read and write, less ceremony, less repetition, easier to test.

I realise some people don't like this API, find hooks unintuitive. But a huge amount of people like the hooks API and prefer it over the class-based one. It's not just a fad, it's just a nice API, it works pretty well.


> Is there anyone who would argue that React Hooks are "intuitive", or at least become that way after you've used them for long enough?

In my experience, they make life much, much easier than using class components as soon as you have any complicated amount of lifecycle management. A lot of componentDidMount, componentDidUpdate, componentWillUnmount, etc stuff collapses down into single useEffect statements, which you can then turn into your own hook wrapper if you're reusing functionality.


I guess I saw lifecycle methods as a code smell anyway. I pretty much only used them when I had to bridge the gap to some third-party code that didn't live nicely within my React/state management world, or when I was forced to do some manual DOM fiddling in one or two cases. Nothing related to my core logic or state would ever live there, so I never reached a point of "complicated lifecycle management".


Some related discussion from a few months back (specifically, a critique of hooks): https://news.ycombinator.com/item?id=22995928

FWIW, I think the single tweet that sums up the reason why hooks are the way they are is this: https://twitter.com/sebmarkbage/status/1094093984211787776

> A property of Hooks is that it forces you to confront them early and then you just learn patterns that don't have the same issues. I don't know if that is worth the tradeoff, but I stick to the claim that this is the tradeoff.

(That's Sebastian Markbåge, who's basically been chief architect of all things on the core React team for the last 5 years or so.)


Our team has seen a boost in productivity thanks to hooks. It has resulted in more straight forward and cleaner component code, making it easier to reason about how they work.

We've been able to get rid of a lot of annoying and confusing stuff when working with class-based components (though perhaps not all of that was related to hooks but also due to early React boilerplate/tutorials which may have proposed things which are now considered bad practice even with class-based components). No more componentDidThis componentWillThat but a simple effect api (the cleanup function can be a bit confusing at times though). No more unclear setState calls but clear and logically separated state updates. No more class method callback binding hacks but simple functions. No more `this` confusion. No more "Pure" and shouldComponentUpdate confusion but a simple memo api. No more weird Redux 'connect' biolerplate but a simple select and dispatch function.

As far as our team is concerned, React has always been a black box and it has helped us a lot being productive. Perhaps it has become harder to reason about how React itself works, but it has definitely become easier to reason about the components built with it.


The best way of thinking about hooks I've seen is they're an attempt to describe all possible states of the component at once, right in the render function.

Instead of tracing through various imperative lifecycle handlers to see how side effects are handled, you have them all in one place. It's kind of a declarative(ish) approach to side effect management.

I personally like hooks and think they achieve this goal pretty well. The API is good, the abstraction maps over decently once you've grokked it (though this is honestly non trivial), and they end up simplifying 80%+ of common usecases.

But... I think it comes with a huge caveat. To consume, hooks are much quicker, easier, cleaner, etc. To write, I'd say less so. The problem is that in order to write and debug custom hooks, you have to deeply understand both the underlying component lifecycle model and the mapping onto the hooks API. This naturally makes creating, modifying and debugging hooks that bit harder than working directly with lifecycle methods in the class model, where there's one layer less of abstraction to deal with.


I've used hooks in 3 different teams now, each team had engineers who weren't really familiar with React before using it with hooks.

The only thing I've noticed is that built-in hooks with dependency arrays consistently caused confusion for newbies - for some reason, people aren't used to thinking in terms of "call this function every time this data changes", but they are very used to thinking in terms of "call this function on initial page load" for example. The second way of thinking will probably lead to bugs or just weird code. Other than that (relatively tiny) hurdle, I don't think I've noticed any other common issues with understanding hooks.

I would be very interested in hearing specific examples of cases where hooks have worked in confusing or unexpected ways.


I think the paradigm of thinking in terms of your data rather than your code is what throws a lot of people off with hooks, but it makes infinitely more sense to me.


I've been following a Github issue about hook support in Flutter, and I understood React hooks much better after reading that than I ever did before. It is clear now what exactly the problems hooks solve are, composable life-cycle state reuse. I think that because most people don't really understand why hooks were even needed, they can't wrap their minds around them.

https://github.com/flutter/flutter/issues/51752


...That doesn't clear up a whole lot for me. Keeping in mind I know React but not Flutter (there may be details that make this inaccurate for Flutter):

> Reusing a State logic across multiple StatefulWidget is very difficult, as soon as that logic relies on multiple life-cycles.

The logic should be inside StatefulWidget, and StatefulWidget reused - so no code duplication or hooking into the parent's lifecycle methods.

> A typical example would be the logic of creating a TextEditingController (but also AnimationController, implicit animations, and many more).

Looks to me more like TextEditingController should be turned into a stateful component so it can be reused in the render - this lets the framework handle its lifecycle and none of the boilerplate is necessary. I've done this a couple times with variations on AnimationController: It uses React.cloneElement on its children to pass down the appropriate state, and because it was itself a component that simply rendered its children, React handled all the lifecycle stuff within that component with no hooks to the parent.

Quick edit: This reply in that issue is very relevant: https://github.com/flutter/flutter/issues/51752#issuecomment...

I can here kinda see where it's coming from, but we've never had reason to use hooks like that, so I guess I just don't see it as as much an issue. Also, a very important part of it that some other comments over here seem to not be aware of:

> In practical terms, there are a few things here. First, it's worth noting Hooks aren't an "extra" API to React. They're the React API for writing Components at this point. I think I'd agree that as an extra feature they wouldn't be very compelling.


The problem arises when you want to reuse a lifecycle function in multiple Stateful or even StatelessWidgets. For example, if you go to the bottom of the issue, I make an example where I needed to have an AnimationController with complex initState and dispose methods. With hooks I could encapsulate all of that and make it work with any Widget I wanted, I didn't have to rewrite it each time.

There are a lot more examples, it is worth going through the entire ~250 comments, even though it may take some time. I only understood after doing so, not necessarily by just reading the initial post.


This is exactly correct and a large driver of the problem for me. React Hooks eschew solving the problem I really care about (shared state) in favor of solving the problem I don't care about 99% of the time (shared life-cycle). On top of that, the API is terrible - magical extra args, stale closures over state are baked in, and using a hidden index to track call order so they can't be used in branches or loops!? I have never written a hook correctly on the first try because the behavior is too unpredictable/subtle.


Maybe you'd like the Vue version which doesn't have those problems. I'm not sure how they implement it however.


I haven't rushed out to hooks when they got out (i'm a preact user not react) to the point that I got an intern tell me "Oh you don't use hooks, I'm not used to work like that".

After digging into them, they are a nice addition for some specific niche scenario where the component is not using any kind of global storage. But from the little experience I had, they bring almost nothing new (I could do the same without them) and they are also kind of difficult to read.

If I had to put a ADR for it, I'd simply skip it trough and specify storage / class components as being much better just because of readability and consistency.

Now maybe they have some better perf but it seems to me they are an addition that came because of the functional frenzy that react has gone trough.

Maybe we got too far, maybe we didn't really need them. Maybe they just look cool.

In the end, i've replaced all my hooks with either GS or Component just because I'm more confident about how my peers will be able to read the code.


I agree with your take, and what bothers me about hooks is that they aren’t even “functional”. They’re making what otherwise look like pure functions into stateful functions, whose return values can change on subsequent calls. This could have been largely averted by passing a hook manager into component functions, an idea that was brought up in the hooks RFC but rejected.

I prefer the class-based approach for stateful components because at least then it’s clear that the component has some state it is managing and how.


From my ultra naive perspective - this was always the case with me.

At the very beginning, Virtual DOM manipulation/management was beyond me. Then they updated the engine to React Fiber. If I thought I understood anything under the hood, I really didn't then.

I believe the author is talking about tiny unexpected side effects as a result of the complexity. Like on a particular hook, 1+1=2 out to 7, 9's. But if you do it just in the right way, you'll get a weird side effect (i.e. 1.0+1=3).

This is a typical result of being a ultra power user and I feel the author's pain.

FWIW, I don't think being a black box is bad. Kernels are black boxes, CPUs are black boxes, to so many of us anyway.

The spirit of what the author is trying to make is - this black box isn't completely predictable. It's only mostly predictable - it needs to get better so everyone can rely on it.


At first I had the exact same reaction as the author. React hooks seem obscure, and you can't understand what happens just by mimicking what you see.

Then I read the docs on React hooks and everything became clear.

Hooks are a new way to think in React, don't try to resist and learn it. Also RTFM. The React official doc is amazingly clear and easy to read.


I don't understand why people don't read the docs for everything.

For me, it's natural for the docs to be the first place I look and to be my source of truth.


Because new features are often close enough to what we know that there's no need to read the docs.

But when we come across a feature we struggle with, it's easier to blame it on bad design than just reading the docs :)


This is kind of just explaining supply and demand. I would say a large proportion of React devs just want it to do the things they need and easily, and hooks certainly aide them. Sure if you need to dig a little deeper then you find that hooks can be a warren of complexity - but nothing stops you from approaching the code directly to understand more (and you can still use classes). For me and my team we actually leverage the 'black box' nature of hooks for the good of the team. Senior members can write high level hooks that they understand and juniors can just use them in their components and not need to go too deep too soon.


It has always been a black box. Not a single one of the people I've worked with over the past four or five years could understand or explain even a fraction of React's internals. Reading the source is a massive undertaking. Of course not every dev has to know the the tools inside out, but it was not unusual to discuss the inner workings of Backbone / MooTools / jQuery / etc back in their day and I think that made all the difference. We have Preact, Riot, Svelte and many other options that are much more accessible, pick one for your next project :)


I agree.

I do not envy people struggling through the adoption curve of using Hooks. I don't know enough about them to know how to "fix" them, nor do I have the time to care about that problem - but I would love to see a different syntax, abstraction, or some kind of guard rails around them.

I might be wrong, but it has always felt like scope & hoisting are the primary language features that hooks operate on... both features that I prefer to avoid.

Adopting them seems to require the same leap of faith that is required with something far more complex like early angular versions. The "I don't get it but I'll just follow the rules" kind of vibe... But the web community seemed to understand and fall in love with Rx a few years ago, so I'm sure hooks can become more well understood, too.


I use React because it pushes the magic into a well tested library and out of my code. React and hooks are great because they make my code so much less magic-filled.


Probably more so that React is gaining complexity in order to lock-in with features. I see a similar pattern with Jest and snapshots feature.

I guess the single boon to the lock-in theory is that JS devs will happily spend time rewriting code to the latest, hottest framework.


One of the things that I don't like about React applies to maybe all frameworks. It's easy to get 90% of the way there, but the last 10% is the hardest. For example, I'm building a real-time websocket app with React. Everything seems pretty easy to build, I'm using hooks, React Router, etc. But coordinating socket connections / reconnections / etc and fitting it into a very functional paradigm is just very very difficult, much more than it would be in a more straightforward library.


For that kind of thing, rather than tightly coupling it to your React tree, you should have components that sanely handle each possible state (no connection, connected but no data yet, new data available, stale cached data available, etc), then have separate handling for the socket stuff that updates data via a global store like Redux.


In case it's not clear, the author is the maintainer of Formik, which is the #1 form library for React. He's also prolific engineer who wrote a litany of other JS projects and is an active contributor to the React community.

His opinions have weight to them, and they happen to resonate with my own experiences.


"becoming" - it has been since the beginning. You have to import the react library or it doesn't work. You create classes but never instantiate them. JSX is invalid JavaScript syntax. It's a veritable cornucopia of black box features, with hooks being just the latest.


But most of those are easily understood the second you say "Babel is going to take the JSX, convert it to javascript, and expects React to be there." Is that crazy? Sure, but it's also pretty easy to update your mental model for.

The most telling thing about hooks to me is that I need a library just to use intersection observer, because the way you have to implement it to replication the same 5 lines of code from vanilla js is so much more complicated.


Pure functions with clearly defined type signatures are always preferable, in my opinion, because there is far less thinking involved. Elm's vdom is done in this way, as is the vdom used in PureScript Halogen.

React is great, and groundbreaking, but with 20/20 hindsight, there are better ways.


The corollary to all this. Companies with open source strategies should really consider hiring and retaining good writers alongside the core developers. This is the reason everyone thinks Dan Abramov created React, he is simply the best communicator when it comes to explaining the mental models around React development. You might have amazing technology, but if you have no one advocating it in a beautiful and powerful way, it won't matter for adoption. React is at a precipice for sure, and there are a bunch of great writers on that team, but there have been a lot of good ones that left recently as well, and that's something Facebook should strongly address.


Funny enough, Dan describes explicitly in his bio that he is not the creator of React


Yeah, I think it is his Twitter byline too!


Can anybody offer a friendly explanation to me as to why it's not wise to update the DOM directly?

I understand that React is supposed to be an efficient and "ergonomic" way to develop for the increasingly complex array of devices out there in the world, but I have had too many poor experiences with React to consider it better than direct UI programming for my needs.


It's perfectly fine to update the DOM yourself. The problem is really that hand writing the vanilla code to do that will be tedious to say the least.

Svelte is essentially that. You write simple components. The compiler checks the dependency graph and converts your code into the vanilla code that would be needed to render those components and make the necessary changes when you modify a reactive variable.

That's why Svelte apps are much faster and smaller. You also write a fraction of the code compared to React/Vue/etc which I think it's actually the best part about Svelte.


I was drawn to Svelte by the performance/bundle size but I fell in love with how simple it is to write components and share data between them.

Each component is just HTML/CSS/JS in a single file, sort of like Vue but cleaner.

If you're curious I recommend either the "rethinking reactivity" talk from the author: https://youtu.be/AdNJ3fydeao

or the tutorial: https://svelte.dev/tutorial/basics

Both are great!


> Each component is just HTML/CSS/JS in a single file, sort of like Vue but cleaner.

A lot cleaner!


One of the motivations for using a virtual DOM as opposed to updating the DOM directly is that DOM updates can be slow, with a minimum duration per change. Applying changes to a virtual DOM can be faster for individual changes, and then those changes can be batch-applied to the actual DOM, minimizing the number of changes to the DOM itself. For larger client applications this can be a win. Like all trade offs, the choice depends on the context.


If that were true how would virtual DOM ever be faster than the DOM? It would still have to update the DOM itself.

What V-DOM is trying to address is tracking what is changing in your application so that it can modify the DOM on your behalf, simplifying app development and reducing bugs, sort of like how a Garbage Collector manages memory for you and gives you similar benefits.

Look at Svelte, it doesn't have a V-DOM and it smokes any V-DOM framework in terms of performance.


  > If that were true how would virtual DOM ever be faster than the DOM? It would still have to update the DOM itself.
It uses a very smart algorithm to diff two vDOMs (previously rendered vs. newly rendered) and "calculates" a minimal* set of operations required to get the current DOM (=prev. rendered vDOM) into the new state of the DOM (=result from current vDOM render). Think in source code patches produced by tools like diff: A patch between two different code tree versions can fit just a few lines and is quickly applied against the tree, while shipping and writing the full tree is more expensive.

*: ideally it would be minimal in a sense there is no smaller/faster representation, but thats of course not the case in real applications.


Neato, so then much like an enterprise service bus (ew old term), there is a bus that comes at a rate of x hertz that events can be loaded onto, and the bus has a certain capacity for events. The busses then load events from the event queue and when it reaches the client, they're all rendered at once. Sounds cool. I guess this is what all of the componentDidMount and componentWillMount is used for?


> Can anybody offer a friendly explanation to me as to why it's not wise to update the DOM directly?

Sure! The fundamental problem that React solves is turning some canonical notion of state into the DOM (with an eye on composability). This is the central problem of web dev. Once your application grows large enough, you will inevitably end up re-implementing a much worse, ad-hoc solution out of $ or innerHTML. You will build your own React and will be responsible for maintaining it! If the scope of your app is small any solution OK.

I'm speaking from experience: I have built several Reacts over a decade or so - so before it existing and a few afterwards.


You'd have to write the code to apply the state to the DOM. React abstracts that in a very optimized way.


I wonder if we are starting to see the initial symptoms of a future exodus. Exodus where though? I don't think Svelte is that place.


React growth has stalled for the past couple of months:

https://npm-stat.com/charts.html?package=react&from=2015-09-...

I moved to Svelte and I'm quite happy.


Have you found any successful patterns outside of Sapper for SSR?

I was demoing Sapper for a side-project and didn't like how much of the server work and routing was relegated to the folder structure. It might just be a personal preference matter, mind you. That and I did find it a bit sticky to get working with TypeScript and it would break frequently after adding that in. So I nixed that idea for now.

Outside of the CLI being pushed so heavily for project structuring, I still find Vue 2 to be one of the simplest to reason around.


You can set up your SSR project very easily.

I actually have a demo of SSR + hydration using Fastify here:

https://github.com/PierBover/svelte-ssr-example

No SPA though.


> I don't think Svelte is that place.

How come? I'm fine working with either React or Svelte, but I prefer Svelte's simplicity and small bundle size. What would be a good React alternative that is not Svelte?


- Svelte seems to have a bit of a problem with large bundle sizes: https://github.com/sveltejs/svelte/issues/2546#issuecomment-...

- Svelte might feel (it does to me at least; although I haven't really worked much with it) a bit too magical. In React, you are explicit about the fact that you want to change your variables and how exactly you want to change them (Rich Harris seems to think that such explicitness is excessive verbosity); while in Svelte you just change a value inline, then boom magic happens. It may be a leap forward, like JSX once was; but it also has an uncomfortable feel to it.


- The large bundle sizes were recently addressed here. It doesn't seem to be a problem in practice: https://github.com/halfnelson/svelte-it-will-scale

- You could perfectly fine write update functions á la React for your component state if that is what you prefer. Personally I don't feel that's necessary and prefer Svelte's direct way.


You hit the problem at 120k unminified.

It only takes a couple feature-rich libraries to hit that number. Even medium-sized business apps can hit that number on their own pretty easily (without including any libraries)

> In practice, you're unlikely to hit that inflection point on any given page of your app, as long as you're using code-splitting (which Sapper gives you OOTB)

That is straight-up fiction. If you bundle split correctly, you put React and other shared libraries in ONE bundle that is shared by all your component bundles. If you're coding an actual app, they'll wind up needing most of those bundles at which point the problem doesn't go away.

Detecting similar functions and combining them is possible (though it will probably add substantially to compile time). I have no doubt that if svelte continues to grow, it will have to handle this problem. I somehow doubt they'll say it's just a minor feature update affecting just a few users when they finally get that work done. Don't forget that reusing code more also allows the JIT to optimize it to get you better performance too.


> Svelte seems to have a bit of a problem with large bundle sizes

For medium to large projects this is easily addressable with code splitting.

For smaller projects Svelte will beat most frameworks out there in terms of bundle size.

https://krausest.github.io/js-framework-benchmark/current.ht...


Inferno is 11% larger bundle size, but is faster at all the things but one (the loss is less than 1/5 the margin of error) while using less memory too. It doesn't take too much more code to make up a mere 17kb size difference.

Preact is 4.8% larger bundle size and a bit slower, but since the unzipped framework is around 6kb, it takes very little code to flat-out beat Svelte in bundle size (there's a mere 7kb difference which decreases with each new component).

Both of these allow you to use the numerous React libraries out there. The added productivity from using these is often going to result in tens or hundreds of thousands less money spent on the project. If they add substantially to the bundle size, then you rapidly cross the point where Svelte is both more code and (in the case of Inferno) also slower.


I've used Inferno on a couple of projects. It is faster, but the difference with Svelte is negligible in real world usage. Even in scenarios that really push the perf (eg: realtime visualizations) Svelte works beautifully.

The big point you're missing in your analysis is that in a real world app Inferno or Preact won't be sufficient to do your job. For example will you probably add other packages to manage state (eg: MobX) or do transitions. Maybe little utilities like classnames[1]? Svelte already includes all those by default.

I will agree there is a sweet spot around 150-200kB where you could get away with Inferno/Preact/etc without code splitting and the Svelte bundle would be higher.

In practice you're not very likely to hit the inflection point of Svelte. For bigger projects you'd be using code splitting anyway, with any framework (unless you're some kind of savage).

> Both of these allow you to use the numerous React libraries out there.

It's true the Svelte ecosystem is small, but that advantage depends a lot on what you're building.

It would certainly be risky to use Svelte for an enterprise app, which tend to be more generic. OTOH if you have custom requirements all those react libraries are pretty much useless.

Also, if this argument had any real weight for dismissing Svelte entirely we'd still be using jQuery. Today the Svelte ecosystem looks very much like the React ecosystem when I started using it 5 years ago and look where we are now. React was experimental back then and now its become the choice for enterprise.

[1] https://www.npmjs.com/package/classnames


The JavaScript community is not very critical; we accept whatever framework developers put out unquestioningly. This is how we end up terms like "transclusion" and the community just laps it up. React started as a simple and elegant library -- anyone with knowledge of basic JavaScript and HTML could glance at the code and understand what it is doing. Sadly it has become more complex since then, and I wouldn't be surprised if the next release has "transclusion" and whatnot.


"transclusion" was coined by Ted Nelson in 1980.


I feel like hooks actually trend more towards "anyone with knowledge of basic JavaScript and HTML could glance at the code and understand what it is doing".

I think the community has trended to more knowledgeable / trying new things, and using more complexity as time goes on.

Everything seems elegant and simple at the start....


A decade ago I decided that I should take longevity of team members as a virtue signal on project health. Boy, was I wrong.

As a project maintainer, your facility with the codebase is entirely based on long-term memory (unless you actively fight it). Every new important thing about the code is just one more thing for you to remember, and you quickly can lose sight of how many concepts you need to juggle to reason about the code in a new-to-you scenario.

When that number exceeds short term memory capacity, you start creating an underclass of developers (or worse, teammates).

It’s easier to prevent this than to fix it, and I’m still trying to develop ways to determine if you’ve crossed that line. The best is always to sit and watch people use the code and see where the struggle. Try to make that happen. If you can’t, I feel like a good proxy is this: if there are features that you get hives just thinking about how much code you’d have to change to get it to work? You’re probably close to the line or over it. If you’re the only person who doesn’t get hives? You’ve crossed over it.


Totally agree with this article. I am operationally allergic to complexity and React us fully complex these days. Based on this pain I did an experiment with a new application.

I just recently developed a complete 12 component app using AlpineJS ... probably pushing the boundaries, but it's awesome!

Components have their own internal state and reactively update their part of the UI using Alpine Directives. We have data CRUD ops with the databases, dynamic tables, dynamic forms, UI panes with dynamic content, etc.

For updates across/between components, we use messaging between components which also triggers reactive updates via updates to message receivers' local state, as needed. QED.

Works beautifully and with 12 components on the SPA (and growing) this is no Hello World or TO DO app. Not by a long shot. Oh, and for the win, no build step at all. Just reload. Time to paint hovering at about 1.7ms.

Tech stack: Go web and API server. CockroachDB. AlpineJS. TailwindCSS and the awesome TailwindUI components.


Hooks just aren't a good solution to most of the problems of front-end dev. They're abstruse, hide implementation details that don't need to be hidden, and make many common behaviours much more complicated to implement.


React is simple it's just a few hundred lines of code, it's easy to understand in an afternoon. Just make sure you pull in a JSX transpiler, and something to do your routing, oh and you'll want something to store your state of course, don't forget that - oh remember to pull in the right version of the transpiler that support decorators for your state management (you do know what decorators are, right?). What do you mean you have a conflicting dependency in your existing codebase? Just fork that repo and upgrade it, that won't take long and cause a bunch of other problems.


Reading through this thread seems to validate the point of the article. A lot of people agreeing that hooks and other features are too complex or hard to understand, and then just as many people arguing that they're actually simple and make perfect sense if you can just manage to understand them properly.

This seems to happen in almost every discussion about react over the past couple years.

My point is that I don't quite understand the purpose of arguing that something is not complicated after so many people have struggled with it. I feel like those people's experiences a priori proves it is a difficult topic.


Something can be difficult simply because it's new: there's work in learning the new thing and updating old code even if the new thing is easier than the old thing.


It is true. Full disclosure - I'm very inexperienced when it comes to javascript - it is on par with my German skills - I can do basic shopping, order a coffee or get a bus ticket, get from A to B but that's it. But I do feel like it's been a black box by design from the start. At the end of the day, we are talking about transpiling code. Which is fine(depending on the definition of transpiling to begin with). If we look at how C affected Assembly, there's no question that the appearance of C skyrocketed the entire CS field in general: Even the most basic of "hello world" programs is a testimony of that. At this point Assembly is in the Cobol universe - a handful of people know it to an extent at which they can work with it. But in the case of React... That really isn't the case - the fundamental problem I see with React(and the entire NPM universe for that matter) is that they try to make a simple solution more simple by making it more complicated and convoluted. On a more general note, the web is broken. It has gone against it's core principles and design. HTML was meant to serve readable documents and that's it. Javascript's purpose was to add some interactivity. But in this day and age, according to reacters anyway, HTML is pretty much Assembly or Cobol, while javascript is C. Which in theory sounds great as far as the analogy goes but in the real world, javascript's purpose was never to take over. It's purpose was to supplement. The flaws in React(and all other 5000000 frameworks) are a symptom of it, not the cause.


As a developer with 15 years of JavaScript experience who has recently had to learn React & React hooks:

They're fine, but weird. There's a lot to like in React, but I constantly wonder whether I've joined a cult. Somebody learned a couple of cute tricks and wants to use them _everywhere_, no matter if they fit the situation or not. Because of this there are a lot of do's and dont's that probably could be avoided with a different design. And there is a lot of gray area in between, specific things the React manual wants me to avoid but in the end I cannot (and I have to quote a whole lot of blog posts from various known React developers to my code reviewer to prove they were really necessary).

Classes have their failings and inexperienced (or overzealous) developers can often turn them into a big mess. These are also well known problems to the computer science community that has come up with a number of ways to manage the mess. Hooks are just a completely React concept where no previous knowledge has any use. Despite looking innocent they have a load of problems and peculiarities, just like classes and methods do. I constantly wonder why they had to go and reinvent the wheel and currently still do not feel like it was worth it.

Learning new things is great and I am glad I got the chance to learn React and its hooks. Now that the project is slowly coming to an end however I am also glad I will soon start learning something else, perhaps something a little less specific to a particular ecosystem.


Being a "black box" is good. I don't have any expertise with React in particular, but any complex enough framework will break down when you extend it beyond the official documented APIs and start relying on undocumented behaviour. Nobody guarantees it will work after the next version bump.

I'm speaking from past experience with Django. Years ago I naïvely made the mistake of assuming that clean, readable source code in the framework implies a contract between the API author and user.


More than React I am excited by what Svelte is doing. No concurrent mode, no super duper runtime magic that needs 1MB of runtime. It analyzes existing code and figures out what uses what, and the code output is hyper optimized so only the things that need to be changed are changed when a variable is set. Svelte runs around react in terms of both startup and runtime performance.

It's like the difference between gas guzzling engine with 100 moving parts and an electric motor with a fewer moving parts but way better mileage.

That for me is true brilliance and thinking of UI as a reactive thing.

Hooks is a giant mindfuck because you have state bound to functions, when 99.99% of your other functions behave like good ol' functions, take inputs from params and return results. If you want state, classes are made to hold state in a thing called `this`. This is how 99.99% of all things in JS work.


> 1MB

React is about 5 kb.


I recently gave Ember (Octane) a try on a project and couldn’t have been happier with the simplicity and productivity in comparison to React.

The React community seems to want to over complicate everything lately and spend more time arguing about philosophy than getting shit done.


I find it very, very sad that Ember lost the marketing war. It was painful to work with for the first 5 years or so but then became a real pleasure. I'll never understand why anyone would prefer JSX over templates. I like opinionated frameworks like Rails and Ember because, even if it's not initially designed that way, a "right way" to do things becomes apparent over time and it's built-in, documented and blogged about. You could switch companies every month and be productive in days because you know where everything should be and how it should be done (mostly). Yes, you can do everything wrong and it will still "work" but it's difficult to get anything done the wrong way in an opinionated framework. When you find yourself struggling hard to do something that should be relatively simple, it means you're doing it wrong. In contrast, React gives devs more freedom to reinvent the wheel and so when you dig in to a new-to-you React code base, you're completely lost and must learn how the previous dev decided to architect things, which can be a total nightmare. Redux feels like a valiant effort to make React more opinionated and remove the opportunity for devs to repeatedly make bad bad decisions or write similar code in multiple different ways, but it doesn't fully solve the problem. I'd choose Ember over React in a second if they were equals in terms of mindshare but trying to hire someone who wants to work in Ember is nearly impossible.


FWIW, Redux has never been pitched as "an effort to make React more opinionated". It's always been about trying to make state management more predictable.

See my post "The Tao of Redux, Part 1: Implementation and Intent" for details on the original design goals of Redux:

https://blog.isquaredsoftware.com/2017/05/idiomatic-redux-ta...


That's why I said "feels". Redux is quite obviously about making state management better but just try to build a reasonably sized app using the Context api instead of Redux and you'll quickly realize that the structured, opinionated, "right way" of doing things in Redux makes for a much happier experience.


Heh. As a Redux maintainer, I do appreciate seeing comments like this :)

Btw, if you haven't yet seen our official Redux Toolkit package, you should check it out. It includes utilities to simplify several common Redux use cases, including store setup, defining reducers, immutable update logic, and even creating entire "slices" of state at once:

https://redux-toolkit.js.org

Also, I just published a brand-new "Redux Essentials" core docs tutorial, which teaches "how to use Redux, the right way", using our latest recommended tools and practices like Redux Toolkit and the React-Redux hooks API. I'd encourage you to check it out even if you're already familiar with Redux:

https://redux.js.org/tutorials/essentials/part-1-overview-co...


I'm actually on "Performance and Normalizing Data" right now. :) The documentation and tutorial is really well done, so thanks for that! I'm glad I attempted to build something without Redux first because at every step of the documentation/tutorial my brain just keeps exploding with "wow, this is going to make my life so much better" and helps me understand why it's built the way it is.

Also, the toolkit is great and feels very Rails-y by providing default, built-in (and I'd argue opinionated) ways of doing things that simplifies development and reduces design decisions. Much appreciated.


Thank you, it's really great to hear that feedback!

Totally agree that RTK works best if you already know how to write Redux code "by hand", so that you're familiar with the concepts and can see what the abstractions are doing for you.

That said, my goal for that "Essentials" tutorial is that folks who have never used Redux before (like, say, someone in the middle of a typical bootcamp) would hopefully be able to start writing real Redux code using RTK and be productive with it, even if they don't understand everything that's going on under the hood. The feedback we've gotten on this new tutorial, as well as on RTK in general, tell me we've mostly managed to hit that goal.

FWIW, my next task is to rewrite the existing "Basics/Advanced" tutorial sequence. It will still be a "bottom-up" explanation that teaches the underlying mechanics and shows how to do things "by hand", but I want to clean it up considerably to remove outdated references and show simpler patterns.

If you're interested, my notes on how I want to redo it are here:

https://github.com/reduxjs/redux/issues/3855

If you've got any feedback on the contents of the existing tutorial and what you'd like to see improved, please feel free to leave a comment there.


They didn't lose the marketing war. Ember back in the day was ember-data way or the highway. If your API wasn't truly RESTful you were fucked. This is what killed it.

Same reason why MeteorJS died, it was mongodb or the highway.


Ember-data was definitely a contributing factor, although one could argue that you could build your own system, just like a lot of people do with React.


It’s funny how the author attributes hooks to functional programming hype when in fact the allow state to be mutated, removing referential integrity from functional components to some degree.


I’ve been thinking about the “je ne sais quoi” that makes hooks troublesome for a lot of developers and I think it comes down to this: hooks are heavily reliant on memo-ization, and memo-ization is a form of caching. Maybe the worst form, since it creates lots of micro-caches throughout your code.

Along with GOTO statements, global variables, and bare thread models, cache consistency is a well known bane of programmers. For some reason though, it seems “memoization considered harmful” has not become a meme yet.


Isn't abstraction of any sorts essentially creating a 'black box' I.e the higher level system doesn't need to understand the lower level system as it's not need or isn't relevant.

My thoughts are it's scary for engineers to feel like they are abstracting themselves away from a lower level systems, a bit like how it's hard for managers of people to let go the tasks they used to do themselves...


Hooks is something I found no problem understanding. That's in total contrary to majority. This makes me wonder if I did really understand it.


I don't think there's a lot to understand. The issue is classes and hooks deal with complexity the in opposite ways.

Working with hooks drops you into programming with functions instead of objects. The component lifecycle in the background rather than foreground and state becomes spread out into different layers of functions instead of centralized.

They are two very different modes of thinking. I came in very late to React. After digging through the classes I inherited from a previous developer, I was struggling to understand what was happening. After reading up on hooks, I immediately got what React was and was able to understand classes better.

Of course, now the app has both classes and hooks. Any future developer who comes along will have fun with that.


After memorising the rules surrounding hooks and how they work I've managed to have a mostly positive dev experience with them. That said having to keep track of the rules, with or without a linter, feels like walking a tightrope with a safety net. Sure I'm not going to get hurt if I fall, but I didn't want to walk the tightrope in the first place.


In my opinion JS was never meant to be used the way it is in all these frameworks. It should be used to do very simple things to improve the user experience. Modern web development is the result of meddlesome engineers abandoning the KISS principle trying to solve a problem outside of their reach (web browsers).


Avoid React if you can, keep your tooling and frameworks minimal and simple for productivity and high performance.


React hooks I think are 70% cool and 30% anti-pattern.

The problem is that there are subtle bugs that just aren't obvious at first.

Here's a simple one.

let count: number = 0;

const myCallback = React.useCallback(() => { ++count; return count; }, []);

... so if you had a button that read the value of 'count' it would always return zero.

The reason why is that useCallback caches the value of 'count' and you get the stale version each time.

You have to add 'count' in a dependency on useCallback before the last paren.

There are about 2-4 of these that I need to write down and document but this one has bitten me most often.

Also, React, in general, can't work well with Typescript to catch compiler issues.

For example, Typescript can catch compile errors when you're building a component and you're missing a variable name.

With React context it's more of a global and if you are using a component which doesn't have context setup you will/could get a runtime error or at least a bad bug.

It would be MUCH better, IMO, to have a React-like language that was Typescript aware from the beginning.


> You have to add 'count' in a dependency on useCallback before the last paren.

My linter yells at me that there's going to be a bug if I do that, have you looked into your linting settings?


I saw that recently they added this to eslint... you're using eslint or tslint?


Is there any doc about how this caching is implemented ? I still don't understand why we need to feed this dependency array to have an up to date version of the count variable.


Not Typescript, but elm[0] was the React-like language.

[0] https://elm-lang.org/


The addition of hooks feels more like an ideological decision than anything. The current fad in the JS world is for functional programming, even if misusing hooks can completely crash your application (this happens if hooks are run in an unexpected order).


I for one would love to see Crank.js take off in popularity, shoot up in usage, implement hooks, then be consumed by the next light weight super focuses JS framework.

I think after 20 years of this repeating pattern JS frameworks might finally die off. We can only hope!


I don't understand. people can try Svelte in few hours and for every experienced frontend engineer, it's obvious that React is not only slow but anti pattern. IMO Svelte is the best possible answer at least for now.


On the contrary, I think that React has done an admirable job of maintaining an elegant core feature set. We are free to (and probably should) completely ignore concurrent mode absent a very clear use case.


The amount of javascript used for the simplest of websites is getting out of hand. In 2025 we'll be back at "server-side rendering", aka mostly static sites, I promise.


hn.js is the only framework I need: https://news.ycombinator.com/hn.js


you guys need to learn Svelte XD http://svelte.dev/ less pain, more beauty


"less pain, more beauty"

That would actually be a great catch phrase for Svelte :)


I know almost nothing of React but this looks eerily similar to the (in-)famous Drupal hooks. Back in 2005-2006 there were articles like this [1] which were mostly caused by people not understanding (or mis-understanding) how the hook system was supposed to work.

[1] https://www.drupal.org/forum/general/general-discussion/2006...



Nice headline, but a lacking article.


As non native speaker I had to look for “black box” in the English dictionary:

> (informal) a complex system whose internals are not easily understood.

So what the article author does not understand of React internals? I don’t care about React internals either until the API is well written and easy to understand. Hooks did not go in this direction :)


Soooo, who’s been keeping up to date with angular & observables. Couldn’t be happier.


Please list specific actual links where people say that classes are better.

I love hooks.


Disagree. React hooks are great. Takes us less than half the code to build the same things and more reusable.

Learn it. Jquery feels like a black box compared to JS but it’s where things are headed, especially when it has demonstrable impact to the pace of web development.


I don’t get it. You don’t really need to understand how React works, you just need it to work. If you’re building a React app you’re probably just building some simple CRUD like thing. What are you going to abandon React for? Some other black box?


The author has addressed this in the article:

> Remember that React is supposed to take care of the “how” so that we can focus on the “what” of our apps. This mantra though, assumes that we can predict the “how”-part correctly.

Their claim is that it's becoming increasingly difficult to predict how React is supposed to work in different scenarios.


Hasn’t been my experience. The author must not be very experienced in working with React.


Perhaps the experience disparity goes the other way.


Yeah "black box" is the totally wrong phrase/metaphor here.

"Black box" means you don't know what happens INSIDE the box. A very succesful software abstraction might be a black box, this isn't generally considered a negative in software. A good "black box" is completely predictable from it's interface, even though you have no idea what's actually going on inside of it.

To me, "accessing disk IO" is a "black box", I have only a vague idea what happens inside the black box when I ask to read or write bytes; and I don't need to, because it works reliably and my very simple mental model of how it works serves me. (If I was doing realtime or high performance or something, I might need to go inside the 'black box', making it no longer a 'black box' that you can't see inside, but I am not and have not).

Wikipedia: "In science, computing, and engineering, a black box is a device, system or object which can be viewed in terms of its inputs and outputs (or transfer characteristics), without any knowledge of its internal workings."

But that's not actually what OP is talking about.

The author is not actually complaining that it's a "black box", he's complaining that the inputs and outputs of black box are too hard to understand, that the mental model of what the black box does is too complex, that it's no longer predictable what it does.

This article might get upvotes because people agree with that basic conclusion, it matches their experience. But it's a pretty poorly written article. It has no examples or evidence, and it's central point is poorly expressed using the wrong terminology or metaphor.


> If you’re building a React app you’re probably just building some simple CRUD like thing.

Simple CRUD-like thing? Why would you reach for a front-end framework such as React to build it in the first place? Ideally, React should be used to solve sufficiently complex problems.


Indeed. I don't understand how my car works, but I am able to use it to get around.


How useful are react editors where you drag and drop components?


Missing examples or clear review to support this argument


FYI, this article is from 2019.


you guys need to learn Svelte http://svelte.dev/ less pain, more beautiful :3


This was always the case. React always totally sucked, but you all jumped on the bandwagon instead of using something simpler. It surprises me that they made it worse over time. But it doesn't surprise me that all the fanaddicts are coming out to defend the newly discovered flaws and complexity, and responding to any criticism not with cool confidence or generous reason, but ideological hysterics.

Why'd you ever sign up for React in the first place? Are you now too invested and deluded by sunk cost fallacy to admit your flaw and get out? Just keep sinking more into it. Who does that benefit?

Maybe if FB wants to tie up startup competition with convolution...


It's sad that we live in a time that the truth gets systematically downvoted like this. Many experienced developers had been saying this about React for a long time; it's bloated and over-engineered. Like ORMs; they just keep creating new problems and then inventing new solutions to patch up the old problems and introduce new problems at the same time.

It's all about where the capital is. Give me a few million of dollars in marketing budget and I can convince all developers on earth to use Angular 1 (with a different project name).


Thanks for saying that. Yeah, it is about this time we live in. It's like the internet was supposed to make us all more open minded to new info, but instead all the unfamiliar-to-each-of-us-info made us all more hard-shelled and narrow minded. So anything not part of our worldview is a scary threat that we need to respond with hostility to.

It doesn't matter what's true. It matters what confirms existing biases. Paradoxically I think people used to be more open minded before the internet, because it was safe to be. They weren't swimming in a infinite ocean of unfamiliar new ideas, they could afford to be open without much risk of having to do the hard work of challenging their beliefs and updating their worldview at every turn.

It is totally about marketing budget as well. In this age of "outside my worldview is fearful, I must respond with hostility" a consequence is you get more group-think and safety in numbers type behavior. So it is easy with enough capital to create these tribes of zealots for particular stacks. It's not adaptive, it's not true, but that doesn't matter. It's safe and comforting.

I just don't wanna work with tools that suck, as I guess you don't too.


Another consequence of this age we live in, that I recently discovered is it's basically impossible to change anyone's mind on the internet. It's not just because it's strangers, or because it's text, tho that does make it harder. It's the dynamic I state above. I used to think it was worth sharing and discussing ideas because maybe I could contribute to somebody else. Now I realize that nobody can change their mind because of what I do. If they somehow did change their mind, they were simply open and ready for it from their own state, and it was accidental that I was involved, it could have been another person or idea. If I bring to them really valuable (as in really surprising) information (the highest quality ideas), the dynamic above ensures they cannot hear it and must respond with hostility. And the lowest quality ideas are ones where people agree with what I say, since those ideas are already widely known. So I have learned to let go of wanting to share my ideas with people online and discuss, or being upset about downvotes. Downvotes mostly indicate quality and entropy. Nowadays I only say what I want for myself...and don't get into discussions, because it's just people trying to prove they're right, prove someone else is wrong, protect their worldview, just pathetic stuff, and I don't want to be part of it.


True. The main reason I write comments on HN is for the handful of outliers who still understand logic and reason and are not blinded by power or consensus. I only comment on articles where my view is contradictory. I don't comment on the articles which I agree about because that doesn't add any value to society for the exact reasons that you mentioned here.

I believe that there are enough intelligent people around to avoid taking us back to the feudal dark ages.


thanks :) ;p xx


React should be put in a black box. And buried somewhere nobody can find it.


React started going down the path of "redux". Lots of sugar on top and blog-driven-development. We use it today reluctantly, but the bloat is hardcore.

Goddamn 'useMemo'? - come on son.

I'm looking forward to abandoning ship, this is getting crazy and I don't have the same energy I did when I was 19 reading blogs all night and writing code katas. I just want to get work done and go home.


This is a really disappointing take on so many fronts.

First, definitely lacks a historical perspective. The React team is certainly not new to accusations of banking their platform on certain mental/implementation/stylistic decisions which people REALLY scratched their head at, only to then become the behemoth of a framework that it is. JSX???? CSS and JS in the same file??? Etc.

But more importantly, this completely overlooks the amazing work the core team has done to make sure you DO NOT NEED TO TOUCH ANY OF THIS STUFF AT ALL if you never want to. React powers one of the most complicated and widely available web apps in the world. That the company and team building it are including tools and philosophies which feel awkward for your CRUD app should simply feel... right. But what certainly doesn't feel right is to see the core team build out more and more features, which support more and more advances and highly specialized use-cases, only to then see the community turn on them somehow because it is "too complicated" or a black box.


The author addresses this as well:

> I think a good ol’ Pete Hunt-style “Thinking in X mode” blog post would go a long way.

They point out that maybe all that's missing is a simple explanation of the thinking behind the new React features is, much like React and its developers did when they first introduced ground breaking features.


[flagged]


It's comforting to hear other people who share similar opinions about this. As an independent open source developer, it's clear to me that corporations have taken over open source and have been actively suppressing independent projects.

I've been very fortunate that my open source project was able to get a lot of attention early on (5 years ago) and has been able to get a lot of steady traffic from word-of-mouth since. I don't know how anyone could independently launch a successful OSS project these days.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: