Hacker Read top | best | new | newcomments | leaders | about | bookmarklet login

Wasn't react first designed in standard ml, without classes? Then classes were bolted on in the js rewrite - and hooks are closer to the original design?

https://www.reactiflux.com/transcripts/jordan-walke

> So I continued to explore framework-izing these ideas, and I had implemented several iterations of what eventually became React, in a few languages - one of the first explorations began as a rough implementation of the reconciler and component model in Standard ML (CreateClass was a "module function"). This was really great because SML embraces immutability by default which is natural when building React style components. We naturally wanted to deploy UI to web browsers, and at the time, the compile-to-JS landscape was not as mature as it is now - I don't even think source maps existed yet. So it made sense to port that exploration to JavaScript (...)

> One thing I noticed that when people were creating point to point bindings in their more traditional "MVC" app structure, it would almost always end up requiring "computable" bindings which invoke a function anytime a mutable cell had received a "change event". All these "computable bindings" ended up chaining together and small changes would end up causing large recomputation of the majority of the UI. I realized that functions already do transform inputs into outputs, and if we could just find a way to reinvoke those functions repeatedly, and quickly enough, that we could be much more expressive and concise, at not much more performance cost that the chain reaction that "computed bindings" would result in anyways.



sort by: page size:

Thank you for this latter link where the original author of React describes its beginning.

After reading it, I finally feel like I'm starting to understand where React came from, why it's designed the way it is.

The paradigm shift that React brought to JavaScript was to "bend the language" to implement concepts and design patterns from ML, a functional language with roots in Lisp, with static typing, algebraic data types, and foundation in lambda calculus and category theory.

When you joked that it was "shoehorned" into JS, I got an insight into the reason why some design decisions in React feel awkward and strangely non-idiomatic. It explains, in part, the strong emotional reactions seen in this discussion thread, a number of justified opinions, its problems as well as benefits.

I've been skeptical of the design of React Hooks, and still am, but now I'm interested in learning its influences, to understand the logic behind them. I wish that it had been implemented to be more "React-agnostic", like JSX, as generic extension to the JavaScript language.


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.


I was just going off my own experience with React through the years. It was very hard to compose behavior with class based components. We had to create higher order components that had functions as children which could pass down data as arguments to the child function. It really made a mess of the component hierarchy. Now you can create reusable custom hooks that can be used from any component.

The old class based way of doing things was a slap in the face for anyone expecting a "reactive functional ui library" and it put me off react until they did the proper hooks implementation.

See this is interesting because I always found it hard to keep track of the lifecycle and state changes in React classes (especially in actual production code which quickly devolved into a tangled mess) but found functions and hooks extremely intuitive and once they were introduced. And refactoring and composability became way easier.

Exactly. React made composing components natural. Hooks made composing state and logic natural. For all its faults React deserves a lot more credit for this. Really the ideas behind hooks need a new language to make them shine and this compiler is a step in that direction.

Hook-using functions basically are classes, just with utterly bizarre method and property declaration syntax and some strange and unhelpful behaviors.

I mean, they ultimately associate lists of properties and functions (methods, if you like) with a component object instance (yes, object) down in the React internals. Sure, access to them is FIFO rather than a lookup table, but that still looks a whole lot like very-weird classes/objects being reimplemented in a language that already has decent-enough ones.

Now, the trouble was certain optimizations and features were probably going to be hard to impossible to achieve while supporting both functional- and class-based components more-or-less equally, and the easy path forward was to let class components become more powerful and functional components slip to second-class (haha), but instead they put object/class-like features in their functions so they could have functions (but very much stateful/side-effecty, so WTF is the point?) lead the way, for whatever reason.


I really like React. I don't know if this particular pattern was explored before, at least I didn't see it, and I used plenty of UI libraries, from WinAPI, MFC to Java Swing and plenty of web frameworks.

I think that JSX support is a genius thing. Especially with modern TypeScript. I spent so many hours because of string-typed templates that I really value templates integrated within a language.

I really liked original React version with classes. It had its rough edges, but it was simple and accessible to me.

Modern React with functions is not simple. It's so far from simple. I consider myself pretty talented developer. But those hooks - I think last time I had to spend that amount of time is when I learned Scheme continuations. That thing really broke my mind. Well, hooks didn't break my mind, but they just seems to be very easy on the surface yet very hard below surface. I read plenty of articles yet I still don't fully understand them (although I think that at least I can use them without bugs).

For me React is like ORM. It's very powerful tool. I allows to tremendously cut the development time. But it requires absolutely expert knowledge on the team. And it looks so deceptively simple at the same time. This is a bad place for technology to be in.


IMO hooks are a DSL implemented in js. React went from class to function components to hooks as preferred practices. In the process, the previous was not cleaned up (until very recently, maybe still, you needed a class component to catch exceptions in a component). It feels like change for changes sake, were only new features are explored without making the whole consistent.

I like React a lot. A simple conceptual model, like elm or other frameworks mentioned here, would work better that this constant change.


Hooks were what made me choose React to migrate to from AngularJS at work. I really like the concept of (state) => ui, but had no interest in react’s former class-based API. It was too complex. With hooks, I can write code in a more functional style, and even though they’re a little weird I think it results in more maintainable code.

I really wanted to push for using Reagent in Clojurescript, or something like re-frame that uses it, since CLJS has much better enforcement of and support for immutability-by-default and function composition. Everything that custom hooks do is handled by plain CLJS functions. It feels closer to meeting the design goals of React than React itself does, even with hooks.

It’s a hard sell though when I’m the only one at the company who knows the language. Maybe someday...


Maybe, but in my experience whenever I encounter an incomprehensible mess of hooks it usually ends up because devs were not using all the tools that react provides.

For example a flurry of setStates could be wrapped up in one single state. If it gets too complex - into a reducer.

Components that don’t benefit much from splitting up could have their business logic wrapped into a context, and let the view code be just jsx without all the interweaving of code and templates.

Maybe the one benefit of classes was like it forced you to think in business logic, then render. React still has that, you just need to dive a bit deeper into its toolbox.

The result usually turns out much more flexible - contexts neatly wrap business logic for all of its descendants, classes don’t.

I think this was maybe because react actually allows you to write messy code, and it’s still performant and works. But in the end it just kinda postpones the inevitable maintenance burden.

I guess solid.js from the looks of it might postpone it a bit more. I just worry that solid looks more like magic, and some invariant somewhere will just break and I wouldn’t know what sequence of reactions actually led to that infinite loop that crashed the page. Haven’t tried it myself though, might more understandable in the end…


React hooks are procedural programming constructs in a thin veneer of FP. They're about as functional as java was object oriented.

The old class based way of doing things was much more explicit.

They weren't though. They looked explicit, but what was actually happening wasn't what appeared to be happening. Dn Abramov wrote a good blog post about the subtle bugs that can sneak into class components - https://overreacted.io/how-are-function-components-different...

At least, hooks should take some kind of "context" and "name" parameters so that they are in spirit a pure function. Then you could also call them in loops and if blocks without problems.

Dan also addressed a lot of the 'why are hooks like that?' questions in another post that goes into some of the designs the React team rejected. https://overreacted.io/why-do-hooks-rely-on-call-order/

Hooks can be hard to reason about but they make code a bit less error prone because when they don't work they fail completely. Classes don't. Classes work most of the time. That is so much worse.


It's good that I wrote:

> Not in the sense that React itself is functional or declarative (it isn't albeit its roots are in Ocaml)

At the beginning of React there were two different components: class-based and pure functional components. Pure functional components rendering has always depended _uniquely_ on its props. No surprises. This introduced a very large number of developers to indeed a declarative/functional style of programming which only depended on the inputs in an era when components were written with local state. Several libraries like Redux, which was Elm-inspired, further introduced millions of developers of combining a declarative/functional/reactive paradigm with handling state without mutations but messages.

Context, then hooks and other features broke this paradigm, whatever is the final result does not depend anymore uniquely on the inputs. React team believes the net result is positive.

I myself with others who commented in this thread and plenty of people I know where introduced to this style of programming with React and then migrated to more strict libraries in the TypeScript ecosystem or other languages such as PureScript, Scala, Elm, Haskell, etc.


I agree with this take! And class-scoped callbacks kept the render function so clean, I feel like hooks really muddled up the API with regards to render. It also created far-more proprietary-to-React logic.

The sense I get is that the original React model has some pretty significant complexities, especially around shouldRender and prop / state analysis, and hooks present a big improvement on that.

I don’t think that the class-vs-function divide is the fundamental reason for the problems with the old model or the improvements with the new model. Rather, I think the learnings from the original approach informed the system and resulted in a step forward.

I find that once I need to manage a nontrivial amount of state, the functional model really feels wrong — useContext, I’m looking at you! And I wouldn’t be surprised if we end up with another turn of the crank that introduces a class-based (or prototype-based) approach with a better set of abstractions at some point down the line.


I am "the react guy" -- but before that I built knockout applications with requirejs & angular applications with coffeescript and gulp, and before that with a 2000 line long script.js & jquery ;)

I don't really disagree with anything you said, except to point out that a lot of the current crop of web devs have never experienced what it is to build an app without any abstraction such as React, and quite understandably have no idea what problems it is doing for them.

I do know that since hopping onto react with all of that ~baggage~ context, I have never wanted to program UIs with a different model. It is true that hooks introduce a layer of abstraction that is sometimes difficult to reason about, but IMO they boil down the problems we faced with class components/lifecycle/server rendering gotchas, and put them front and center - forcing you to confront and fix them rather than settling for a solution that works 99% of the time.


But I wish new frameworks stayed away from inventing new language syntax. Not only is it a cognitive burden on programmers, it throws all the tooling off.

From Svelte: {#each cats as { id, name }, i}

JavaScript already has facility for loops and mapping, and relying on that will automatically get you tooling/IDE support. React handles this aspect quite well, and to me that's a point in favor of React.

I do agree with your post - especially on hooks being a step backward.


That’s the thing though - hooks aren’t JS. They don’t allow for control flow. Hooks are a language that superficially looks like JS. I’m with you on not inventing new languages, and I wish that React didn’t step so far off that path itself…
next

Legal | privacy