Hacker News new | past | comments | ask | show | jobs | submit login
How Does setState Know What to Do? (overreacted.io)
218 points by danabramov 3 months ago | hide | past | web | favorite | 65 comments



> But as we have seen today, the base class setState() implementation has been an illusion all along. It doesn’t do anything except forwarding the call to the current renderer. And useState Hook does exactly the same thing.

This is worded a bit weirdly. The fact that there is some indirection and the meat of the `setState` is in the renderer and not in the component doesn't really make `setState` an illusion. A call to `setState` still does exactly what we thought it did.


Maybe I need to rephrase. I meant that many people imagine Component class as being the meat of the codebase, heavily operating on `this` and updating things on it.

Similarly folks often imagine `this.state` being the source of truth (and thus Hooks seem too ephemeral).

But both of them are indirections to the same place elsewhere. And state for both of them is kept in the renderer. For classes it’s synced to `this.state` at the last moment so you can read it but `this` is not the source of truth.


> I meant that many people imagine Component class as being the meat of the codebase, heavily operating on `this` and updating things on it.

Yeah maybe. Even when it's not true it is still a valid way of looking at it I think. In the abstract sense that's what's being modelled here with the API, right? The fact that the internals are different is an implementation detail. Of course, it might be an interesting detail, hence your blogpost.

> Similarly folks often imagine `this.state` being the source of truth (and thus Hooks seem too ephemeral).

I still don't understand why this is though. In some of my projects I actually manage my own local state on the component class (without this.state/setState) and auto `forceRender` when something changes. In those cases my state is super sync and everything works fine. With the additional benefit of my local domain logic being modular: I can read my state after having updated it and it works like expected. So know I can write multiple methods dealing with my local state and compose them freely — like actual OO.

I understand the hooks world is a different story, but in the compat component world it all seemed just fine. Why doesn't react use `this.state` as the source of truth, or update it more aggressively so it at least looks like the source of truth to me? Perf reasons? Is it worth it?


> > And useState Hook does exactly the same thing.

Except it does more bookkeeping behind the scenes to know which state you want (since you're not passing in an identificator). Wonder why they chose that solution, as it's just more magic for really no gain, and it will give you funny bugs if you call it in a loop or in a condition.


I wrote about why here:

https://medium.com/@dan_abramov/making-sense-of-react-hooks-...

(TLDR: that makes custom Hooks very powerful)


From hooks documentation: If you look at a typical React application in React DevTools, you will likely find a “wrapper hell” of components surrounded by layers of providers, consumers, higher-order components, render props, and other abstractions.

React applications using the MVC model don't have this problem. In MVC Components just handle rendering. Stateful logic go into controllers. I think React is getting unnecessarily complicated because of the "everything is a component" model.

I strongly recommend comparing/contrasting this with MVC model. Here's an MVC router that works well with React: https://github.com/edman3d/mvc-router

It is a pity that React was originally designed to be the V in MVC, and then the developer community took it in a different direction.


Did you read the linked article? I think you’re overfocusing on one argument and might be missing the bigger picture. In my experience MVC doesn’t really help with the problems that extracting and reusing custom Hooks attempts to solve. Controllers aren’t composable in the way functions are. (An alternative take on this is that Hooks are controller-ish.)


From the linked article: Components are more powerful, but they have to render some UI. This makes them inconvenient for sharing non-visual logic. This is how we end up with complex patterns like render props and higher-order components.

But this is a problem with how some applications are using React, where they make everything a React component. You don't need to make everything a React component. In the MVC model only things that put stuff on the screen need to be React components. You are saying Hooks are better than controllers--and maybe they are. But when the problem is stated as in the above paragraph, then it is not obvious that Hooks are the solution. Maybe the problem should be stated better.


FYI, this is Dan Abramov's blog. He's one of the developers working on the React team. I'd highly suggest checking out his other posts if you use React, they're all superb.


I do the DevRel* for Chrome DevTools. Dan is remarkably good at DevRel. I've pinged him on a few occasions, and to my recollection he's always replied very promptly, always with a helpful answer. My impression is that he's like that with anyone who has a reasonably well-thought-out question. Which, if true, is amazing considering the size of the React community. Aside from React's own merits, I would wager that Dan's DevRel superpowers have been a non-trivial factor in React's success.

* Developer relations, on the off chance anyone is unfamiliar with the term. A DevRel team for a developer product like React would be in charge of communicating new features, changes, best practices, etc. to the React developer community, answering technical questions on how to use React, and relaying community feedback to the React team.


I just learned that DevRel is a thing, I just thought it is a non-trivial part of a normal project but not that it was categorized separately (or I'd call it tech advocate). Not only that, I think that DevRel is the best indicator of success of any project! Basic design, documentation, etc are needed, but once those are covered it's DevRel what sets projects success apart.

Famous DevRel I know and what they've been promoting to great success:

- Dan Abramov, Redux and React.

- Evan You, Vue.js

- Lea Verou, Prism, Bliss and CSS in general.

- "@dhh", Ruby on Rails.

- Sindre Sorhus, npm and indie JS.

Note: I just say they have greatly helped to the success, no that these are their projects.

On the other hand, we all know some projects that succeed despite their founders being really bad at DevRel... but those are so rare and basically just put a lot of efforts in something related but not the same (marketing, first to the market, 10x better technically, etc).

My main focus right now is learning how to get better at this since I'd love to do OSS fulltime. Any tip on how to get there would be greatly appreciated. I'm trying to learn mainly from Dan and Evan since IMHO they are next-level in this specific area :)

PS, since you work for Chrome DevTools, I imagine you are in Google. I think, besides the issues of Angular 1->2, the real reason Angular stayed behind is that there were no highly visible DevRels.


FWIW my job role is just software developer. I try to help people because I like being a part of the community and like explaining things to others that somebody explained to me. But I’m not officially a DevRel. Although I guess I fit the shoes.


Right, didn’t mean to imply that you only did DevRel. I think most React users know that you’re on the core team. Just wanted to suggest to the general HN community that your consistent efforts around helping the React community might be a factor of React’s success. Whenever there’s a post here on HN about why framework A is a success whereas framework B is a flop, the focus is usually on technical factors or developer ergonomics.


> But I’m not officially a DevRel. Although I guess I fit the shoes.

Those are usually the best DevRel folks imho. Love the work you do!


Taylor Otwell with Laravel definitely fits this category too.


- RhodiumToad on Postgres


Is there any way (other than the chrome bug tracker) for devs to talk to you guys about Dev tool bugs, or suggestions?

There are definitely some lingering low pri bugs in the issue tracker that would improve the QoL that would really help the dev tools experience.

Example: https://bugs.chromium.org/p/chromium/issues/detail?id=771144

This happens every time. So I just stopped moving the tabs, but if the dev tools are not wide enough to show the (ever increasing) number of tabs, it’s always the 3rd party ones that get pushed off.


I would LOVE if this was fixed in Chrome.


I love getting the inside view. Dan's asides about how the team decided to use this or that approach are priceless.


Never knew he started a blog until recently when someone posted his blog post on how React tell a class from a function.

Good stuff if you want to know how React work internally.


That's because he only started it recently. His first post was November 30 this year, and he already has 5 high-quality articles!


I love these posts but despite the warning I'm sure some of the things here will end-up in React junior positions interviews.


״However, this has always led to obscure bugs so Hooks force you to solve the package duplication before it costs you."

So basically the fact hooks doesn't support multiple react instances isn't a but but a feature :D?


More like "this tool wasn't designed to work that way, so to use this part of the tool, you'll have to conform to the way it was intended to be used."


Those working on projects. What do you prefer? Should i choose React or Vue?


Try both, and see which one you prefer.

Vue first though, as it's easier to get started with it and it will get a sense of what minimal setup you should expect. Then try to match that with react.

If you start by following most react tutorials, they will make you begin with something way more complicated that it needs to be and you will get discouragedd.

Both have a "cli" tool. Everybody tell you to start with it. I strongly advise against it, as it's the best way to not understand a thing about what you are doing and make bad decisions.

Find a tutorial that starts with the bare lib (no webpack, no transpilation, nothing but a script tag), for both vue and react. Then when you know how this work, find a minimal webpack based tutorial.

Then when you know those basics, use the cli tool, but immediatly use the eject feature. Read the result to understand the whole shebang.

Once you have done that, you can start any project using the cli without eject, and be confident you know what's going on. It will make you not only very productive, but also will let you take decision based on what you know, and not what other people wants you to know.

Now, I personnaly prefer Vue as I find the lib easier to work with, the community saner and the documentation is one of the best I've read, even including non JS projects. But again, make an educated choice.


> If you start by following most react tutorials, they will make you begin with something way more complicated that it needs to be and you will get discouraged.

Can't agree more with this. There are quite a few reasons I think those starter-kits and tutorials are very harmful especially to new developers. Figuring out how your tsconfig/webpack/babelrcs/state-handlers/etc all fit together should be something that should certainly be done and learned incrementally.

Perhaps the issue is the amount of boilerplate you need to start a simple app. There should be a flask[1] like starter for react/vue apps. Parcel seems like the closest thing but its still not obvious to me why they demo 4 files to get started [2] -- we already dynamically transforming and compiling everything why not just have a single `index.js` with a Index/Main entrypoint?

Is there anything out there to do something as simple as:

    import * as React from "react"
    import {Html, Body, Title} from "parcel"

    const Index = () => {
        return (
            <Html>
            <Title>MySite</Title>
            <Body>
                <h1>Hello world!</h1>
            </Body>
            </Html>
        )
    }
with a `cmd {run,build} index.{jsx,tsx}`

[1] https://github.com/pallets/flask/#a-simple-example

[2] https://parceljs.org


Create React App does pretty much with all the complexity hidden behind ’react-scripts’ you can optionally eject out of if needed sometime in the future.

The steps are pretty much

npx create-react-app && yarn start and finally yarn build for a production ready build.


Using "Create React App" as a beginer is the best way to have no idea of what you are doing, and make terrible decisions for what follows next.


I'd love if you would elaborate on that so the Create React App documentation[0] and the official recommended tutorial[1] could be improved on

[0]: https://facebook.github.io/create-react-app/ [1]: https://reactjs.org/tutorial/tutorial.html

edit: Saw your points above and while I do not agree I can understand your point of view.


I already contribute to the python community. No time for another one, sorry.


I would recommend just following the official React tutorial: https://reactjs.org/tutorial/tutorial.html

There are many other tutorials on the web but the official one has had a lot of work put in to making it seamless and letting you get a feel for what it's like to work with React without throwing too many tangential ideas at you.


No it makes you start in an online pastebin env. It's the easy way for the tutorial writter, not the easy way for the learner.

I teach React regularly, I tried all methods. The only one that make people click is to make them use a flat html page and React.createElement() manually in it first. On their laptop. Offline. With no other tools than a text editor.

This way, you remove the magic, and when you bring it back, people make good use of it.

Magic is good for power users. It's a bad things as a beginer's tool though.


I'd prefer React even more now with the promising Hooks. I would not easily let a random person here choose for me with all his/her opinions. It really depends on what you want to do with either library.

For work/income I'd choose React as there seem to be more jobs for that. Also in the long term it feels like a pretty solid choice. React has a very big and active community, an outstanding development team, and so many codebases in the world are build on it. React will linger on for quite a while I dare to guess.

IMHO it is not really a React vs Vue thing, you could also go for Ember or Angular. Just pick the one that feels and works good for you and fulfils your personal needs we cannot assess.


I've noticed that developers more accustomed to backend work, or projects that already have a heavy backend, prefer Vue. It's easier to grok because they're used to handlebar template syntax and directives. I've also noticed that Vue is preferred by people coming from jQuery and/or Wordpress type work. It's less intimidating for some unknown (to me anyway) reason.

I've pushed production Vue and React projects and my personal preference is React. I haven't worked with React Hooks yet but it looks like a game-changer and would make my codebases a lot cleaner. I prefer JSX although Vue also has JSX support, but I've yet to work on a project with complete opt-in for it. React also sets you up for React-Native in some way, in case you're considering targeting native platforms as well.

At the end of the day, don't pick React or Vue for a frontend that doesn't need it. For example, your personal site probably doesn't need a UI library. Then ask what your coworkers feel more comfortable with, if you have any. Finally, check how easy it'll be to integrate with (or migrate to) the existing codebase, if any.

Both libraries and ecosystems are incredible at the moment. You can get a clean and reasonable codebase, performant frontend, and great pace of work with either.

If you do go for the Vue route for professional work, consider donating to Evan's [patreon](https://www.patreon.com/evanyou/overview) or [Open Collective](https://opencollective.com/vuejs). And similarly for [Nuxt](https://opencollective.com/nuxtjs). React et al have venture funding or Facebook behind them for the most part.


If you are gonna work as an individual dev, then you can evaluate both. But if you're in a team, then choose whats best for the team.

Both are good options that nothing serious will come against your way when working on most CRUD apps. If it involves serious computations then you should really evaluate both and select what best fits your usecase.


> If you are gonna work as an individual dev, then you can evaluate both. But if you're in a team, then choose whats best for the team.

This is very important. Resources can often be more important than tech.


This is very much personal preference. I would suggest to look at their docs & create something small for both. Plus try out their 'standard frameworks': Nuxt & Next.js.


Create React App and Create React Native App have both been very productive and mature tools to get things rolling fast.


Great Stuff


Doesn’t answer the question.


These posts are cool. I'm planning on writing a set of react interview questions based on them.


Given this disclaimer at the top of every article, that sounds a bit inappropriate:

> Disclaimer: Just like most other posts on this blog, you don’t actually need to know any of that to be productive with React. This post is for those who like to see what’s behind the curtain. Completely optional!


I only want my team to be composed of those who like to see what's behind the curtain.


Everyone knows the best teams are homogeneous, and everyone knows that if a candidate hasn't looked behind the curtain of React, then they probably don't look behind the curtains of anything.


There's dozens of layers of curtains, and nobody has this level of expertise at all of them.

Have you read and understood all of tcp.c? Can we quiz you on the USB protocol?


This is from the second post:

> Just like in my previous post, you don’t need to know this to be productive in React. I didn’t know this for years. Please don’t turn this into an interview question. In fact, this post is more about JavaScript than it is about React.

https://overreacted.io/how-does-react-tell-a-class-from-a-fu...


Wouldn't you just be testing if they read the blog posts?


React is a bit less hot today than it was a few weeks ago. What changed is that FireFox released support for Shadow DOM. Also Microsoft is moving to Chromium. Which means Shadow DOM is suddenly hot and technologies that don’t support Shadow DOM, including React, became a bit cold.


Huh? React does support Shadow DOM and other Web Components APIs [0]. You can use Web Components in React components just fine.

[0] https://reactjs.org/docs/web-components.html


Yes of course you can use Web Conponents in React. But React components are not Web Components and don’t use Shadow DOM.


I’m not sure what your point is. React components can use Shadow DOM if they want, but they don’t have to. Neither do Web Components. React components can be rendered to DOM nodes, but they can also be rendered to lots of other things.


Lets say you want to implement this element:

    <ProductPicker />
You can implement it as a React component in which case it only works in React applications, and will be brittle because of the global nature of js and css.

You can implement the same element as a Web Component and now it will work in any application regardless of framework... you can just drop in and it will work. If your application has conflicting css classes or element ids or javascript variables the Web Component will still work reliably. That’s hot! React components will feel a bit cold as cross-framework Web Components take over.


> and will be brittle because of the global nature of js and css.

Modules have existed in JavaScript for several years now, and there are numerous solutions for dealing with global CSS (CSS Modules, Glamor, etc). There are many large production web applications using React, probably generating billions of dollars worth of business - I don’t think they’re “brittle”.

> You can implement the same element as a Web Component and now it will work in any application regardless of framework... you can just drop in and it will work.

Sure, you can just drop a Web Component into any framework. People use React for a lot more than just defining components - they use it for data fetching, animations, etc.

> If your application has conflicting css classes or element ids or javascript variables the Web Component will still work reliably.

If this is the case I think you’ve got much bigger problems with your app than choosing which JavaScript library you’re going to use. React apps will work despite conflicting element IDs as well, but they’re still a bug in your app. Web Components don’t magically get rid of JavaScript variables. CSS classes still matter unless your whole app is going to live in the Shadow DOM, which isn’t really what the Shadow DOM is for.

> That’s hot! React components will feel a bit cold as cross-framework Web Components take over.

Again - you can use both. They solve different problems.


>> People use React for a lot more than just defining components - they use it for data fetching, animations, etc.

Using React for data fetching and animations seems like a bad idea, it is not the best tool for the job.

React is popular today, tomorrow it may be View, then there will be something else. If you can write reusable components that work in all of todays frameworks and tomorrows, while sticking to standards, while taking advantage of things like Shadow DOM, why would you still limit yourself to React? I am not saying the entire application should be a Web Component, but certainly reusable parts should be written as Web Components so that they can work in all your applications even if they don’t all use the same framework and in future applications that use yet-to-be-invented framework.


That isn’t really an argument for React or any other framework going out of fashion in the next few weeks though? It seems rather contrived to think that Web Components are inherently better because they’re standardised. React isn’t using unstandardised browser features, and it’s not as though you’re not still reliant upon your chosen Web Components library being maintained in future.


Web Components are directly implemented by browsers so you don’t need a “Web Components library”. So yes they are inherently better because they work in every application and every framework. This universal compatibility and better reliability makes Web Components a better choice today for creating reusable components, than React.


> Web Components are directly implemented by browsers so you don’t need a “Web Components library”.

I mean a collections of components like Polymer. Unless you plan on maintaining everything yourself, both React and Web Components share the same problem here.

> This universal compatibility and better reliability makes Web Components a better choice today for creating reusable components, than React.

You can mix and match any and all frameworks and Web Components if you try want. And again: React and Web Components mostly solve different problems. One isn’t going to directly cannibalise the other. You can use both.


No technology becomes more/less hot in a period of a couple weeks, not even JS frameworks.


I want to believe this. However, I also feel bewildered when I check the news of what all has happened in js frameworks in the past 3 years. Especially true, if I consider how different the big frameworks of today are, compared to the same frameworks 2 years ago.


Really, if you're talking three years ago, React was already widespread. The main change is that Angular.js back then was still widespread as well, and that Vue wasn't really.

Sure, things have changed (e.g. TypeScript is far more accessible today), but if you've been doing React for the past few years, the changes haven't been that drastic, and primarily for the better (e.g. Create React App, that mainly allowed you to forget things, rather than having to learn new things).


A technology could become cold in an instant if a superior solution was found. I don't think that's true with React though


Any actually used technology won't become cold instantly because old systems will already depend on it and won't be rewritten immediately


Sadly, shadow dom in FF is unpleasantly broken for any serious use of web components, up to the latest nighty edition.

Focus is broken so you can't tab between inputs. For example, if you compose forms using web components, you'll lose keyboard control over focus movement in your app.


And it's fixed for FF 65 hopefully. :) Web components are now working fine in FF.




Applications are open for YC Summer 2019

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

Search: