It's basically the magic vs explicit discussion all over again. Like usually in this discussion, the magic approach is really appealing until it doesn't work, and then the pro-explicit people will go all "told you so" on you.
I personally really prefer explicit, having cut my fingers on magic one time too often. Instead, I'll gladly create classes if the thing I'm making has its own state (of any kind).
In fact I pretty much disagree with the current trend of wanting to shoehorn everything into this idea of declarative and/or functional programming. Especially in a language like JS, functional programming and some cherry-picked ideas from OO mesh really well together. For example, if you allow me to drift a little, did you know that you can add methods to the prototype of an Immutable.Record? You can even use class syntax! More to the point, if there's one place where OO ideas shine, it's UI components. A lot of OO ideas were particularly designed and developed for UIs.
Just like "let" and "const" let me communicate to the reader whether a variable is going to change, I like how in React-land "class" and "function" let me communicate to the reader whether a component has mutable state. Hooks feels like a hack to be able to change the value of a "const" without turning it into a "let". Get over yourself, make it a "let" already.
So for me, Hooks is an attempt to throw the baby out with the bath water. I don't experience the problem it's trying to solve. I like classes when they're appropriate.
I get the argument that custom hooks allow for easier reuse than higher order components, but I think the difference is marginal; you have to wrap your mind around the exact same complexity. Plus I think higher order components themselves are overused, but that's another story.
But! The React people strike me as a rather reasonable bunch. I strongly doubt they're going to move React into a direction where you're forced to make your state (slightly more) implicit. There's too varied a community around React now. I think React with classes and React with hooks can perfectly coexist. Also if my favorite open source React tool adopts hooks and forces me to do the same here and there, then sure I might be grumpy for a few minutes but in the end, well, I'll survive.
> It's basically the magic vs explicit discussion all over again. Like usually in this discussion, the magic approach is really appealing until it doesn't work, and then the pro-explicit people will go all "told you so" on you.
Well... Have any "pro-explicit people" gone all "told you so" about all the magic that's going on with setState?
I don't think so. I don't think it's a binary magic vs explicit choice. I usually lean towards explicit, but as setState demonstrates, it's possible to find some kind of balance where the benefits of the magic outweigh the downsides, or at least are not that bad of a choice.
There's nothing wrong with `setState`, in my opinion. However, it does do magic. Although it might feel like it immediately sets the state to be what you provide it as argument, it actually schedules a state update to be performed later when React feels like it. That's why it's best practice to provide an updated function rather than a plain object: if the new state depends on the previous one, and you read the previous state before calling `setState`, then that can lead to problematic behaviour.
(And of course, there's the magic of the returned object not being set as the new state, but rather being merged into the previous one.)
I think the more relevant analogy between hooks and setState is that setState uses essentially the exact same technique as hooks to keep track of which component is calling it, namely, React keeps track of which component it’s rendering, and setState mutates some “global” state. A lot of people seem to think that setState stores state in the instance of the React component class, but that’s not the case (and that wouldn’t work for a lot of React features and optimizations).
Is this true? Maybe I'm reading it wrong but this.setState in a React.Component just transparently calls out to `this.updater`[1] where `this.updater` is injected by the particular platform library (eg react-dom). At least in react-dom/server's case, a unique `updater` object exists per-component[2], so it's effectively a private instance field; and those state changes apply to a similarly per-component `inst.state`[3]
You can also prove this by calling setState with the wrong `this`: `this.setState.call({}, {x:1})` blows up. So the `this` is required, unlike how `useState` works.
Which is also something beginner React users often discover the hard way when they start with class instance variables, wonder why things don't work as they expect, and then have to learn to use setState.
At least from the principle of least surprise, Hooks don't have that particular learning hump of trying to use a built-in language feature (class instance variables) and finding out the hard way that they don't work as expected.
> setState() enqueues changes to the component state and tells React that this component and its children need to be re-rendered with the updated state.
(Emphasis mine.)
> I'm guessing you mean for a global store with shared state? Local components aren't singletons.
No, local state, the one you set using `setState`. The offical docs don't actually recommend always using an updater function, but it's the primary method they explain, and my inclination is to better be safe than sorry:
> If the next state depends on the current state, we recommend using the updater function form, instead
Apparently nothing, but from how I read it a lot of magic is going on underneath the covers (which I cannot really imagine, if react is as simple as it claims).
It's basically the magic vs explicit discussion all over again. Like usually in this discussion, the magic approach is really appealing until it doesn't work, and then the pro-explicit people will go all "told you so" on you.
I personally really prefer explicit, having cut my fingers on magic one time too often. Instead, I'll gladly create classes if the thing I'm making has its own state (of any kind).
In fact I pretty much disagree with the current trend of wanting to shoehorn everything into this idea of declarative and/or functional programming. Especially in a language like JS, functional programming and some cherry-picked ideas from OO mesh really well together. For example, if you allow me to drift a little, did you know that you can add methods to the prototype of an Immutable.Record? You can even use class syntax! More to the point, if there's one place where OO ideas shine, it's UI components. A lot of OO ideas were particularly designed and developed for UIs.
Just like "let" and "const" let me communicate to the reader whether a variable is going to change, I like how in React-land "class" and "function" let me communicate to the reader whether a component has mutable state. Hooks feels like a hack to be able to change the value of a "const" without turning it into a "let". Get over yourself, make it a "let" already.
So for me, Hooks is an attempt to throw the baby out with the bath water. I don't experience the problem it's trying to solve. I like classes when they're appropriate.
I get the argument that custom hooks allow for easier reuse than higher order components, but I think the difference is marginal; you have to wrap your mind around the exact same complexity. Plus I think higher order components themselves are overused, but that's another story.
But! The React people strike me as a rather reasonable bunch. I strongly doubt they're going to move React into a direction where you're forced to make your state (slightly more) implicit. There's too varied a community around React now. I think React with classes and React with hooks can perfectly coexist. Also if my favorite open source React tool adopts hooks and forces me to do the same here and there, then sure I might be grumpy for a few minutes but in the end, well, I'll survive.