Hacker News new | ask | show | jobs
by hardwaresofton 3007 days ago
disclaimer: I don't like react. Outside of dom node diffing and a focus on components I don't think it brings much to the table considering the considerable complexity it brings.

It seems like react gets re-written and APIs undergoes drastic changes every few months. I'm not complaining about churn (I don't write react), but rather that maybe React isn't the right tool to be hyping up, or pointing newcomers to JS at to look into/use.

I don't remember any other supposedly simple library having had this many major rewrites/api changes. I don't think I've ever seen something like this in KnockoutJS or even Angular1 for a long time (even though the way you had to handle $scope and apply/digest cycles was terrible). Relative newcomers like Mithril and Vue seem to get this stuff right without requiring as much breaking changes. Maybe they owe their simplified structures to some of the new thought to what React inspired, but it seems like they're actually simple (Vue's documentation is amazing, concise, and you can actually render Vue in the browser to get started quickly).

Maybe it's time to rethink whether React is a good tool. There's no way I would recommend React to anyone (beginner or intermediate) over something like Vue these days.

For example, I don't know what HOC (and am thoroughly uninterested, it sounds like the same kind of thing you only need to know when you're chest-deep in React land) is but it sounds like a hack necessary because of a bad design decision.

[EDIT] - Took a few seconds to look up HOCs (Higher Order Components) and they're a bad example of what I think is incidental complexity inside React but I think my point still stands. To clarify, here's my thesis:

React is complex (both internally, evidenced by multiple rewrites, and with the tooling it forces you to use, evidenced by needing to download a zip file to start, or touch webpack), but masquerades as a simple library.

3 comments

We maintain more than 50,000 components at Facebook, and I don’t believe your assessment that “APIs undergoes drastic changes every few months” is accurate. The component API has barely changed since the initial release five years ago.

When we need to make changes, it’s the team of 8 people that need to port all those dozens of thousands of components to new APIs. It would be infeasible for us to break APIs every few months, or to do so in a manual way. This is why we embrace automatic codemod scripts.

There have been some breaking changes between major releases (which have a roughly yearly—not monthly—cadence) but we always provided automatic scripts that convert your code as much of your code as possible automatically: https://github.com/reactjs/react-codemod.

We also call attention to the automated migration scripts in all major release blog posts (for example: https://reactjs.org/blog/2017/09/26/react-v16.0.html#upgradi...).

That’s the only way we could maintain dozens of thousands of components while still moving the library forward.

I hope this information is helpful. You can read more about our commitment to stability without stagnation here: https://reactjs.org/docs/design-principles.html#stability

I apologize -- I should have written "API internals". I did not mean to state that the component API changed a lot, just seemingly that the internals did, with fiber and the like.

I understand the team is hard at work making React better, and there is absolutely no doubt that you are succeeding and react is getting better. However, the amount of large internal changes indicates that as you improve and (most likely) shed unneeded complexity, that there must have been complexity to shed. Obviously no one is perfect, and hindsight is 20/20, but for such a "small" (yes, interacting with the dom is actually super duper hard, and edgecases abound) scope, I've seen more large-ish overhauls than I am comfortable with.

Many internal changes makes me feel like react is more Mongo than RethinkDB (the latter being a document store that actually got most things right and was well engineered but no one ever heard of while mongo started with a badly engineered product, good marketing, and pivoted to relative reliability and good engineering).

I want to also note that I'm not in the target audience for a post like this. There are tons of people who lovingly and productively use React -- I'm not one of them. I am just dumbfounded when people bill react as simple but have never heard of something like Mithril that actually is simple (almost "stupidly" so), and another post at the top of HN means there's that many more people I have to convince to pick something at least slightly simpler when they start doing web development for the first time.

> However, the amount of large internal changes indicates that as you improve and (most likely) shed unneeded complexity, that there must have been complexity to shed.

The v16 rewrite (dubbed "fiber") wasn't just about cleaning up internals- it was about supporting a fundamentally different type of behavior- asynchronous rendering [1]

> Obviously no one is perfect, and hindsight is 20/20, but for such a "small" (yes, interacting with the dom is actually super duper hard, and edgecases abound) scope, I've seen more large-ish overhauls than I am comfortable with.

To be fair, React supports many more targets than just the DOM. In addition to the DOM- there's react-native, react-art, react-music, react-hardware, etc.

Don't mean to sound argumentative, just wanted to add some info in case there were potential misconceptions. :)

1: https://reactjs.org/blog/2018/03/01/sneak-peek-beyond-react-...

This is a huge point that I do often miss when I think about react when used for react development...

You're absolutely not being argumentative -- while I still don't think react is the simplest thing to start with, the explanations that have been given so far seem very very reasonable, feel like an asshole for essentially ranting

>just seemingly that the internals did, with fiber and the like.

We‘ve lived with the same codebase for four years and frankly, it was slowing us down. Not all original abstractions aged well because when React was written, we didn’t really have a lot of experience with React :-)

I don’t think it’s because the original code was bad (I’m not familiar with Mongo so I don't know if that’s what you were implying), but because it’s not very easy to come up with an architecture that is both efficient and targets multiple view output targets (e.g. React Native) from the first attempt. Especially considering support for Native was retrofitted into an existing design at some point. It was also pretty much impossible to foresee the kind of features we’d be working on in a few years before anybody used React.

Some fundamental assumptions in the old codebase were actively preventing us from implementing new features. For example, there was an assumption all over the codebase that a custom component always renders one root, but this prevented us from letting people return arrays from render. There were many small things like this, and at some point it was clear we needed to redesign the internals from scratch.

The Fiber rewrite was about unlocking our larger vision (we recently shared its details: https://reactjs.org/blog/2018/03/01/sneak-peek-beyond-react-...) but it was just as essential for smaller incremental improvements.

Long-requested features that shipped in React 16 like fragments (returning multiple components from render), error boundaries (gracefully recovering from runtime errors), portals (declaratively rendering the child React tree to a different DOM subtree), and an official context API (finally shipped today) would not be possible without rewriting the internals to an architecture that incorporates our learnings about how React should work that we’ve accumulated over the years.

I’d also argue those features (and then ones we’re working towards—please do watch my demo at the previous link!) are a bit more ambitious than “interacting with the DOM”.

> am just dumbfounded when people bill react as simple but have never heard of something like Mithril that actually is simple

I agree React is not simple internally, but that was never the goal. The goal is to make it simple to build products with React, and so far I believe its success speaks to product developers finding it helpful.

I don’t push for React being used everywhere (and I heard people who used Mithril are happy with it) but I hope this gives some insight into our decision and development process.

We didn’t rewrite React because we wanted to clean a few things up, or because we didn’t know what we were doing. We’re pursuing very specific goals, and a new architecture is essential to enabling them. And there were no multiple rewrites; just one: https://code.facebook.com/posts/1716776591680069/react-16-a-....

Thanks for explaining so much about the process -- I didn't mean that the code was bad, just that there was an unexpected amount of growth.

But hearing what was being dealt with (those blog posts) definitely clears things up for me -- Also as the other commenter mentioned, react is aiming for so much more than the DOM (react native was a visionary/revolutionary achievement IMO, not even trying to blow smoke, I think at this point that's pretty much a fact) it makes sense why and how react has grown the way it has.

Thanks for taking time to clear up my misunderstanding/where I was wrong

For the most part, the changes really shouldn't affect typical users. The biggest change in React from a dev perspective was function components, maybe 2 years ago. If you keep your state outside of React, it's dead simple to use.

I think it's a great library and has only really gotten simpler and better. But, to each their own.

I agree that it's getting simpler and better -- tons of dedicated developers are making that happen. I wasn't trying to say that the rewrite shouldn't have happened or something, I just feel like there's a lot of zealotry festering, so many companies are picking React just to attract developers (anecdotal evidence: https://www.youtube.com/watch?v=u80GTmVtdG4&t=2898s).

My problem is that it was being marketed (heavily) as simple and amazing at the beginning when it simply wasn't. From what I remember, the FB team was explicit about it not being for beginners, but the amount of marketing and trumpeting made that basically impossible, and now bootcamps are teaching it to beginners.

I just am super tired of having to talk people out of using it on their first project after learning and using HTML+CSS for the first time. I always sound like the insane person, saying "react is complicated" when all the marketing and blogs and everything else is saying "react is simple".

const Name = (props) => <div>{props.name}</div>

const Age = (props) => <div>{props.age}</div>

const App = () => <div><Name name={'Zed'}/><Age age={20} /></div>

Is about as simple as it gets. This sort of composability can go _very_ far without needing any of the other API methods.

I looked up HOCs not long after writing the comment, and I agree -- this is much better than the mixin approach that used to be the way (though if I remember correctly, mixins were considered 'temporary' at the time).

This isn't a benefit of react though -- this is just react incorporating a well known functional paradigm, which I don't mind.

IMO If react was simple, this would have been the way to do it from the start -- no mixins detour. This answer would have fallen out (as it now has), if they simply didn't offer a way to inherit functionality, in that manner. If a component is truly just a function from state to output, the obvious way to combine them IS higher order functions.

A HOC is nothing more than a factory in traditional OO programming. Just because you see an acronym you don't understand, doesn't mean the entire framework is flawed
I should have looked up HOC before I wrote that bit -- Higher Order Components do not seem like a particuarly bad design decision, but IIRC this pattern was introduced somewhere around the launch of React 16?

Also, I'm not sure the characterization as a factory is correct, seems closer to higher order functions (at the very least name wise), and/or enhancing features by composition.

Higher order components have been a common pattern since early 2015. https://medium.com/@dan_abramov/mixins-are-dead-long-live-hi... (And like others said, they are relatively simple and draw heavily on prior principles in functional programming.)
Components are just functions -- HOC's are higher order functions. The pattern dropped out like all patterns drop out -- from use. Its nothing specific to React, but to functional programming
Just replied in the other spot -- I understand the similarities now, but I think this points to react still not being as simple as it could be -- if components were really as simple as being functions from state to UI, reacts API would be drastically smaller.

My point is that it's not that simple (for better or for worse, some of the added complexity in the API IS essential IMO), but people still say things like "components are just functions" like it really is that simple.

For example: https://reactjs.org/docs/react-component.html#static-getderi...

This note:

> Note that if a parent component causes your component to re-render, this method will be called even if props have not changed. You may want to compare new and previous values if you only want to handle changes.

Things like that are indications of hidden complexity, in my experience.

To be fair if a function gets called, any functions called from it also... get called (whether arguments to them have changed or not).

So if anything, this particular example speaks more to React components being “just functions” (which is a statement I disagree with—but I don’t think this example is very relevant to that).

It just seems like your misunderstandings are preventing you from understanding React properly, and that those misunderstandings could be rectified by more experience with the library. Learning is inherently difficult but sometimes its best to trust in the process and dive in :)