Live data from Hacker News

Why Do React Hooks Rely on Call Order?

overreacted.io

61–70 of 115 posts

Re: Why Do React Hooks Rely on Call Order?

#61

Earlier quoted context omitted.

It's not really well explained in the article, but the argument against Symbols is that you (client code) have to store them somewhere for reuse in different calls. That is that, you could do... useState("someID") ...and somewhere else (* or in the same place but on a different call) again... useState("someID") ...and this indeed refers to the same item. But using a Symbol, you need to first create it, store it somew…

That’s not really all that different to everyone moving their CSS-in-JS and GraphQL queries out of a functional component body though, is it? This is kind of exactly the scenario Symbols seem to have been intended for. Also... a nitpick, but `new Symbol` always throws a TypeError. And Symbol.for() is a useful escape hatch.

>That’s not really all that different to everyone moving their CSS-in-JS and GraphQL queries out of a functional component body though, is it?

I suggest you to take the `useSubscription` example from the "diamond problem" section and try to convert it to your proposed API. I think you'll see why it falls apart.

(Don't forget effects would also need keys.)

Re: Why Do React Hooks Rely on Call Order?

#62

Earlier quoted context omitted.

In actual use I've seen that Redux apps often wind up with a lot of accidental data dependencies that probably wouldn't have happened without a centralized store. For example devs will lazily use a "currentUser" key in the store for all kinds of unrelated stuff and subtle bugs creep in. Another common problem with Redux is memory issues because various components don't clear their data out of the store when they're u…

I absolutely agree with you and that's been my experience too, I've seen exactly those problems in both my own code and others' code. It took me personally many iterations over various projects to learn the boundaries of where redux makes more sense and where component state makes more sense. That's perhaps the biggest actual inherent problem with redux, that it may implicitly encourage everything to be in the one si…

Yeah my approach now is to use Redux only for state that's shared among a bunch of components. Local state is fine and a lot simpler for things that aren't globally interesting.

Re: Why Do React Hooks Rely on Call Order?

#63

I think this post has actually pushed me back towards Symbol keys perhaps being a good idea. The useFormInput() example under Flaw 3 seems rather contrived – wouldn’t you just pass a Symbol key to useFormInput and it would then pass the key to useState, solving the supposed flaw? If you had to use useState several times in useFormInput, just use a WeakMap (they’re not that scary) with the keys being the Symbols passe…

>wouldn’t you just pass a Symbol key to useFormInput and it would then pass the key to useState, solving the supposed flaw? Then `useFormInput()` wants to add another state (e.g. `isHovered`). How are you going to compose Symbols? We get to the next flaw (manual composition is annoying and error-prone).

> How are you going to compose Symbols?

I would’ve used a WeakMap with Symbol keys that mapped to a list or object containing Symbols.

Sorry if I’m just overlooking something obvious, but most of the examples that I’ve seen to explain why Symbol keys aren’t better than the current proposal seem to be just be examples of badly implemented custom hooks, not necessarily flaws with Symbol keys per se.

Re: Why Do React Hooks Rely on Call Order?

#64

Earlier quoted context omitted.

>wouldn’t you just pass a Symbol key to useFormInput and it would then pass the key to useState, solving the supposed flaw? Then `useFormInput()` wants to add another state (e.g. `isHovered`). How are you going to compose Symbols? We get to the next flaw (manual composition is annoying and error-prone).

> How are you going to compose Symbols? I would’ve used a WeakMap with Symbol keys that mapped to a list or object containing Symbols. Sorry if I’m just overlooking something obvious, but most of the examples that I’ve seen to explain why Symbol keys aren’t better than the current proposal seem to be just be examples of badly implemented custom hooks, not necessarily flaws with Symbol keys per se.

Can you convert the `useSubscription` example from the "diamond problem" section so we can compare "before" and "after"?

A key design goal is that creating a custom Hook is easy. You should be able to literally copy paste part of your component (e.g. a bunch of useState calls and some event handlers) and call it a day.

I'm struggling to see how what you're suggesting could be easy for the end user but maybe I'm missing something.

Re: Why Do React Hooks Rely on Call Order?

#65
post #21

(I edited the post title to include “React” before the “Hooks” to disambiguate. Might be worth editing the submission too!) Hope you’ll enjoy reading it.

I just briefly looked at the examples (and of course followed the twitter boom about it), but what I am not getting is that to me it looks like since useState() is against the principles of pure functional programming. I understand that it implements some kind of inversion-of-control, but just looking at the code it feels like using some global object's method which is a big no-no. Also this importance of ordering re…

It's not a global object—it's an instance of the object for the component you're using. The whole thing's a terrible OOP system in a language that already has a built-in mediocre OOP system, which terrible OOP system is, in the end, just a(n inefficient) pass-through to same built-in mediocre OOP system.

The posters here wondering why you can't name them are on to something. I assume it's because then it'd be too obvious that's what they're doing, and whoever's paying people on that team (I really hope it's not more than one person, it's not hard work, but it probably is) might notice and make them stop, and maybe the React team at FB would even shrink in size, and we can't have that.

I'm not sure what other explanation there could be for such comically-wasteful sandcastle building. I assume it's a combination of individual incentives to work on something not-difficult but flashy and prominent, with project incentives to never need fewer people than they currently have.

Re: Why Do React Hooks Rely on Call Order?

#66
post #34

Isn't the ID problem just a question of the type of the ID? Sure strings would have collisions, but symbols wouldn't.

You can search the article for "symbol" — there's a whole section dedicated to that. :-)

lol, that's what I did, somehow I didn't get any results.

Maybe a typo, thanks for the heads up :)

Re: Why Do React Hooks Rely on Call Order?

#67

I wonder if it would makes sense to enforce hooks being called through a top level React function. To make some of the ordering more explicit function MyReactComponent() { const [ [width, setWidth], [name, setName], ] = React.use( [useWidth], [useName, 'alice'], ); return {width} {name} } admittedly, this is much less clean looking than the current proposal, but, in my mind at least, it makes it a bit more clear that…

I don't understand what exactly you're trying to solve by this (nothing prevents a user from making it conditional) but it definitely has flaw #7 (can't pass values between Hooks).

Ah that's fair about flaw #7

Re: Why Do React Hooks Rely on Call Order?

#68
post #65
post #21

Earlier quoted context omitted.

I just briefly looked at the examples (and of course followed the twitter boom about it), but what I am not getting is that to me it looks like since useState() is against the principles of pure functional programming. I understand that it implements some kind of inversion-of-control, but just looking at the code it feels like using some global object's method which is a big no-no. Also this importance of ordering re…

It's not a global object—it's an instance of the object for the component you're using. The whole thing's a terrible OOP system in a language that already has a built-in mediocre OOP system, which terrible OOP system is, in the end, just a(n inefficient) pass-through to same built-in mediocre OOP system. The posters here wondering why you can't name them are on to something. I assume it's because then it'd be too obv…

>The posters here wondering why you can't name them are on to something

Can’t name what? Not sure I follow.

>I really hope it's not more than one person, it's not hard work, but it probably is

We had from 5 to 8 people on the team at different times. Maybe maintaining one of the most popular open source projects isn’t “hard work” for you but we find it challenging.

>I'm not sure what other explanation there could be for such comically-wasteful sandcastle building.

We try to solve problems that product engineers run into. If you have better ideas we’d love to hear them.

Re: Why Do React Hooks Rely on Call Order?

#69

Earlier quoted context omitted.

Yes, and to some extent it is addressed in the link too (though not really well explained). Symbols do not clash, but they need to be managed/stored by client code. i.e. you need to keep the original Symbol to use it in different calls, while you can use "different equal strings". This is the argument in the article. Whether this is indeed more or less desirable than having order restrictions on calls, that's a diffe…

Symbols don't solve this without extra closure wrapper and Hook "instantiation" (described in flaw #5). Passing a Symbol to custom Hook from outside also doesn't work because a custom Hook may have more than one state. Try to convert the `useSubscription` example to your proposed API (and don't forget effects would also need "IDs") and you'll see what I mean.

Couldn't a custom hook have a map of maps that keep track of this?

The first map gets the symbol that was passed to the custom hook as keys and the maps inside that map would use symbols only the custom hook knows about.

I think your solution is superior in that is more concise and I at least think I understand why you went that way. I'm just trying to understand why the symbol approach wouldn't work.

Re: Why Do React Hooks Rely on Call Order?

#70

Hooks reminds me of tensorflow scopes a little bit, in python: with tf.variable_scope("foo"): with tf.variable_scope("bar"): v = tf.get_variable("v", [1]) assert v.name == "foo/bar/v:0" `v` tensor here will have a generated human readable unique name here: "foo/bar/v:0" It seems with hooks, react uses call order to derive the unique "leaf" hook id for runtime resolving its implementations. However, it would be nice i…

For debugging, we will show Hook tree in DevTools by capturing and parsing stack traces. https://github.com/facebook/react/pull/14085

Could something like this be used to move the "linting" that the react team recommends directly into react itself?

If you can abuse error stack traces to get the call stack, and some trickery to get the string representation of the component function that called the hook (following it through all intermediate custom hooks), you could then have the full text of the function body and know for sure that it's calling a Hook, and from there could run some linting on that internally and scream to the console if a hook is being used incorrectly.

It may have a pretty significant performance and possibly size overhead depending on how much code is needed to inspect the function body and actually do the parsing/linting, but removing the need for a linter ("need" might be too strong of a word?) would make it easier to get started with, and safer to use for developers who, like it or not, don't read docs fully, don't setup or use linters, or just want to throw something together with very little tooling. And obviously it would all be stripped from production builds.

Has the react team explored this idea? and are there reasons that I'm missing that it won't work or isn't ideal?

Post reply on HN