
Introducing Hooks - sophiebits
https://reactjs.org/docs/hooks-intro.html
======
adriancooney
My gut reaction is that Hooks isn't the greatest addition to React. One thing
I've always pitched about React is the clean and extremely explicit API (with
`dangerouslySetInnerHTML` being my favourite example). The hooks API is taking
the dangerous road down to implicitness and magic which can only ever mean bad
things in my book.

It's really not clear to me how calling the setter for these individual pieces
of state triggers a render. It seems the `useState` call is implicitly linked
to the calling component no matter how far down the call stack (with only a
linting check keeping the safety on this footgun). I was also surprised to see
the concept of reducers making their way to the API. We're being told the
"classes are the biggest barrier to learning React" yet the notoriously
difficult concept of reducers has its own method. Don't get me wrong, I _love_
Redux however I'm not sure I can get behind the shade for classes.

I'll have to play around with hooks before I can make a final call though
because I have the utmost respect for everyone behind this project.

An interesting observation: I think this is the first piece of API that
contains the word "assumes" [1].

[1]
[https://www.google.ie/search?q=site%3Areactjs.org%2Fdocs+%22...](https://www.google.ie/search?q=site%3Areactjs.org%2Fdocs+%22assumes%22)

~~~
acemarke
Have you looked at what `React.Component.setState()` actually does under the
hood? The logic isn't implemented in `React.Component` itself - instead, it
tells the core React rendering logic to queue up a re-render. The real work is
all inside React's internals.

I agree that the `useState()` aspect _looks_ a bit magical, but it's
ultimately doing the same thing that `setState()` does in the end. React
already knows what component this is, and you're telling it to queue up a re-
render for that component.

Also interestingly, it seems that `useState()` is actually a wrapper around
`useReducer()`, and not vice-versa :)

~~~
wereHamster
The 'this' in 'this.setState()' tells react which component queued the
setState. With the new API that information is collected by react through..
ehm.. some kind of magic.

I understand why the react developers chose not to make the component an
explicit argument in the new API, as it would open doors to misuse. But magic
never seems to work out in the long run, IME.

~~~
acemarke
I'd agree it's "magic" in the sense that it's not entirely visible to the end
user. But, the key is that React is _already_ tracking _which_ component it
renders as it traverses through the component tree. It's just now also keeping
track of some additional data as it goes through the process of rendering that
component. So in that sense, it's not any more "magical" than any of the
existing render algorithm.

~~~
badestrand
The problem is that the hooks seem to be much more restricting than setState.
You can `if (condition) this.setState({x: 1})` but you can not with hooks
because React keeps track and doesn't allow you to break out of a very narrow
usage.

Look at the rules from the docs:

> Only call Hooks at the top level. Don’t call Hooks inside loops, conditions,
> or nested functions.

> Only call Hooks from React function components. Don’t call Hooks from
> regular JavaScript functions.

I think this will lead to junior developers to not _understand_ the React
framework but to just accept "the way to do things" and do what the docs say,
without ever questioning anything.

~~~
scq
I think those rules only apply to useState and useEffect themselves, and not
to the setState function you get back when you call useState.

~~~
DougBTX
Yes, I think you’re right, there are different restrictions on when useState
and setState, though it is worrying seeing confusion straight away about it.

I wonder about a case where there is an expandable panel in a UI, and when
expanded it should fetch then display data from a web service. Easy enough to
do with this API by splitting the content of the panel out into a second
component, but it is going to be very tempting to wrap that useEffect fetch
call in an `if (expanded)` condition.

On the other hand, there are lots of positives about this design too, the
correctly written code does look very elegant and I can see it solving real
problems.

~~~
trixn
As I understood it you should not opt-in to use state conditionally in your
component but you can still conditionally set the state. That means you should
not conditionally call `useState` but it is fine to conditionally call the
`setState` returned by the `useState`. That is not different to how you would
use state in a class based component where you also wouldn't attach a state
`this.state = {...}` somewhere in the middle of its lifetime. The component
has state from the beginning of its lifetime or it hasn't state at all. There
is not such concept as "Now that you are expanded you will transform into a
stateful component".

------
sadturnip
> In our observation, classes are the biggest barrier to learning React.

As someone who struggled hard with some aspects of learning react, i felt this
to be the absolute opposite. Watching people to combine and spread logic over
dozens of functional components, and drag in other external libraries like
recompose to do stuff like lifecycle hooks, and using HoC's, just to avoid
classes makes my head hurt.

> Only call Hooks at the top level. Don’t call Hooks inside loops, conditions,
> or nested functions.

I really don't like this, and to me this feels really finicky, and
unfortunately the explanation doesn't make me feel warm and fuzzy ether. While
it is great they are adding a linter plugin for it, i feel like this is going
to be really easy to shoot yourself in the foot, and feels like it is relying
on behind the scenes magic too much.

~~~
eloff
I feel the same way! Maybe I'm just getting older, but I like code to be
boring. A class is something everyone can read and understand. If you have to
navigate a maze of HOCs withStateHandlers, enchancers, redux actions, reducers
and connectors you end up needing to open 10-20 files and jump around between
as many functions to build a picture of how a component works. Considering
code is read more often than written - that seems like a huge step backwards.

Hi, I'm Dan. I write boring code. I _love_ Go because it's super boring.

I like to read boring code, write boring code, and then get on with my day. I
don't like long walks through the codebase trying to understand how everything
is wired up in a super-cool functional way. Get off my lawn kids.

~~~
tree_of_item
> A class is something everyone can read and understand.

This is simply not true. Your post is very strange, you just assume classes
are simple and boring but everything else is 10-20 files with fancy magic and
blah blah blah.

The truth is that Dan is wrong about what makes code boring. Immutability is
boring. Dan just likes Go.

~~~
eloff
A class has all the related code in one place in one file (some languages
excepted, base classes excepted, but true enough for React purposes where
inheritance hierarchies are quite limited and rare in my experience.)

I _like_ immutability. It can make code easier to read and understand if done
well. But within reason.

It's not that I'm creating some strawman where the alternative to a class is
10-20 functions across as many files - but that's actually mild compared to
some things I've really seen.

To give an example, about a month ago I had to read a co-workers
implementation of a feature and it was literally a maze of some 30 functions
many of which returning closures, some of which return other closures. With
state scattered all over in withStateHandlers, etc. I spent two hours on a
Saturday trying to understand it and make the changes I needed to make before
I gave up and assigned the ticket to my coworker who wrote it all. Basically
he's the only one now who can modify that code easily (and incidentally he's
away now on leave, if we have to modify that code again, we're screwed.)

So immutability of data is awesome. Immutability of code is not. If it was a
couple boring classes I could have read the code and made all the changes I
needed to make in less than an hour.

Simple an predictable and boring is fantastic where code is concerned. I love
Go not because of the features it has, but specifically because it's limited
enough that the code written in it is almost always easy to understand.

------
AriaMinaei
I went from skeptical to sold in five minutes. This API is absolutely
beautiful. I have quite a few components in each of my projects that do
nothing other than call lifecylcle methods (they render `props.children`).
Composing them is sometimes easy, and sometimes awkward. Especially when
trying to read a value back from a child component.

With the hooks API, that child component can be rewritten as a simple hook,
making it much easily composable.

Thing is, hooks are very simple, and some of them (except `useContext()`) are
expressable with react's current API. I'm surprised that none of us thought of
them earlier.

~~~
vga805
Agreed. Having used React since the beginning and having taught it, this seems
to me its natural evolution. I also thought the API was beautiful. I also
think it will be easier to teach, but I'm less certain about that.

While I think its a great API, I totally understand some of the hesitance
expressed by others. Its more churn, etc., it seems to allow for more
spaghetti code for intermediate devs perhaps. But, I don't mind the churn, to
me, while its been a nuisance, it also often appears like an evolutionary
process.

------
emmanueloga_
Looks like the default way of writing react components in ClojureScript (with
Reagent [1]). Compare:

CLJS, Reagent:

    
    
        (def click-count (r/atom 0))
        (defn counting-component []
          [:div
           "The atom " [:code "click-count"] " has value: "
           @click-count ". "
           [:input {:type "button" :value "Click me!"
                    :on-click #(swap! click-count inc)}]])
    

JS, React + Hooks:

    
    
        function Example() {
          const [count, setCount] = useState(0);
          return (
            <div>
              <p>You clicked {count} times</p>
              <button onClick={() => setCount(count + 1)}>
                Click me
              </button>
            </div>);}
    

Not sure about the name "hooks". Trying to figure out why they name them like
that.

1: [https://reagent-project.github.io/](https://reagent-project.github.io/)

~~~
rpeden
I don't think it's quite the same, is it?

In the Reagent example, you declare the atom outside of the component
function, and that atom would end up shared if there were multiple instances
of the counting component.

In the react example, each instance of the component would have its own
separate state.

Reagent will let you put the atom inside the component, too, so you _can_ do
something very similar to the React example. Just wanted to point out that the
two examples you've got now do different things.

~~~
emmanueloga_
hmmm yeah here's a better example:

    
    
        (defn timer-component []
          (let [seconds-elapsed (r/atom 0)]
            (fn []
              (js/setTimeout #(swap! seconds-elapsed inc) 1000)
              [:div "Seconds Elapsed: " @seconds-elapsed])))
    

Now the atom is defined inside the component function, and is captured by
lexical scope in the returned function. Any timer-components on page will have
their own `seconds-elapsed` state.

~~~
wildermuthn
This was such a common pattern that reagent created a macro for it. But I like
the macro-less code, in that it becomes very clear what is happening. A good
macro reduces complexity by making code concisely simple. A bad macro hides
complexity by making code easy to write.

Frameworks like React succeed when they are built like a good macro.

In this case, React is both hiding complexity (component lifecycles) while
adding unnecessary complexity (a lInter that will inevitably fail). It’s odd
to see React make this move, but not surprising considering that it now has a
larger use-base then ever before.

~~~
emmanueloga_
Are you maybe talking about with-let? I'm fairly new to reagent and not really
familiar with any of its macros

As it turns, there are only 5 macros, and only a some of those seem to be part
of the public API, which is how I found about `with-let` :-)

[https://github.com/reagent-
project/reagent/search?q=defmacro...](https://github.com/reagent-
project/reagent/search?q=defmacro&unscoped_q=defmacro)

------
anonytrary
Unpopular opinion: There are too many cooks. I used React two years ago
because the API was tiny, simple and elegant. They are adding new API features
left and right, and the framework feels very uncoordinated now. The surface
area is way bigger than it needs to be. This is my cue to finally explore
other frameworks.

~~~
fiatjaf
I agree with you, but I've also tried other frameworks and there isn't a
single one that is all-around better than React.

Unless you're willing to migrate to other compile-to-js languages.

~~~
tracker1
If you aren't interested in 3rd party components or React 16+ features... you
could try Inferno or Preact as alternatives with JSX and a similar API.

------
hliyan
"You might be curious how React knows which component useState corresponds to
since we’re not passing anything like this back to React. We’ll answer this
question and many others in the FAQ section."

While I appreciate the functional usage of state, this type of magical
behavior worries me a bit. Wasn't more straightforward semantics possible
(even if the syntax wasn't similarly straightforward)?

~~~
joelg236
In the keynote, Dan talked about how this works. It depends on the order that
useState is called, which makes conditional branches a no-no (there's a linter
for it).

~~~
rhacker
Since JS is single threaded, they are basically keeping track of which
component was last called for render - that way they know useState() calls
attached to which components. If the order changes, then they can't keep track
of the different objects tracked by useState. So treat it like you would class
state - all fields are always there, no matter which functions or conditional
branches you take - hence - do your initialization above all your conditionals
and loops.

Edit: And yes, slight concern of course, it's the got some rough semantic
equivalents to a thread-local in Java, albeit in Java the danger exists
downstream, this danger is only exhibited during initialization it seems.

------
eric_b
There are a lot of gotchas with these. Don't call in conditionals, branches,
loops. Can only be called from function components. Order of invocation
matters (yeck!)

If the goal is helping developers "fall in to the pit of success" I think
classes are a much better option than this.

~~~
lacker
There are a lot of gotchas with the object-oriented way of doing these things
too. Don't set `this.state` directly, don't forget to keep your side effect
logic in `componentWillMount` parallel to your cleanup logic in
`componentWillUnmount`, et cetera.

~~~
eric_b
Yep, no doubt. The problem is they aren't getting rid of old foot guns, just
adding new ones. And the new way with hooks isn't obviously superior to the
old way (debatable to be sure, but with all the constraints hooks are not a
broadly applicable solution to many problems). So now you've got two separate
but equally powerful guns pointed at your feet.

Is that progress? I'm too old to think so.

------
pg_bot
I know I may be in the minority here, but I can't say that I'm a fan of this
feature. I can't envision a scenario where this would be my preferred solution
to any of the problems that they detail. Templates should remain stateless, as
they are far easier to reason about that way. My gut reaction is that this is
a giant step backward.

~~~
boubiyeah
react is not based on logicless templates. Their very first presentation in
2012 or 2013 made that clear. It's a feature.

------
pavlov
Am I getting this right: it’s an implicit global stack for the render loop?
Sounds like a combination of the worst design features of OpenGL and Forth, to
be honest...

OTOH, React has been pretty good about taking discredited design ideas — like
Adobe Flex’s style of mixing XML declarations into ECMAScript code — and
injecting them with new vigor. So maybe this one too is better than the
initial impression.

~~~
danenania
Personally, I loved Flex’s mxml/actionscript combo. Its main (fatal) flaw was
targeting the flash player. At the time, moving to html/js felt like a big
step backwards on developer experience.

~~~
pavlov
Yeah, MXML (and in fact most of Flex) had a lot of good about it.
“Discredited” was too strong a choice of word in my post — I meant something
closer to “unfashionable”.

------
ggregoire
While I agree that class components has always felt like a workaround to
bypass the limitations of function components, and that it's obviously
annoying to rewrite a function component to a class component just to add a
state or a lifecycle method, the following explanation sounds a bit silly to
me:

> In our observation, classes are the biggest barrier to learning React. You
> have to understand how this works in JavaScript, which is very different
> from how it works in most languages. You have to remember to bind the event
> handlers. Without unstable syntax proposals, the code is very verbose.
> People can understand props, state, and top-down data flow perfectly well
> but still struggle with classes. The distinction between function and class
> components in React and when to use each one leads to disagreements even
> between experienced React developers.

A framework shouldn't be designed around the fact that people don't know the
language they are using, right?

Anyway, those hooks look like a good way to solve the issues listed above.
Can't wait to try it out!

~~~
schneidmaster
In the live talk, Sophie also discussed how Javascript classes are difficult
for machines: minifiers aren't able to shorten the names of methods (because
it's apparently hard to work out all the ways that the method could be
invoked), and they cause stability problems with hot code reloading. So there
are benefits beyond ease of use for humans.

(Also, I'm pretty fluent in Javascript and I still forget to bind event
handlers all the time, which suggests to me that it's a counterintuitive
pattern even if I know "how it works" on a technical level. And you either
have to put a bunch of "this.handler = this.handler.bind(this)" in the
constructor, or rely on class properties which are an unstable syntax feature,
both of which are suboptimal.)

~~~
adpirz
It may have been on purpose (came off as a sincere mistake), but Dan Abramov
forgets to bind them in this talk while giving an example. It's a very common
problem, even for the authors of React itself :)

~~~
azangru
It did come off as a sincere mistake, but remember, they had a dry run of the
talks a day or so before. So could have easily been staged. But was hilarious
anyway.

------
nathan_f77
This is really interesting. I'm a big fan of any abstractions that reduce the
amount of code I have to write. Just a personal preference. Other programmers
like to avoid "magic", but I love it.

`useEffect` feels much cleaner than the component lifecycle methods, and I
could add some abstractions on top of those. e.g. a higher-order function that
adds/removes a window event listener, and you can just pass the event and your
callback.

Maybe `useState` could take a second argument that gives the state a "key", so
that it can be called in any order. I can imagine breaking up the `useState`
calls into different functions, and then skipping one of the functions if
something changes. So it might be handy if there was an escape hatch where you
could label each call with an integer or a string.

EDIT: Wow, it would be awesome to use this pattern for my Redux reducers.
Instead of having to connect up all the actions in my container and then prop-
drilling all of the dispatching functions down into my components, it would be
great if I could just import the action creator directly and use it anywhere I
want. Maybe I could add some similar hooking magic to find the store from the
Provider and call dispatch with the action, instead of manually wiring
everything up. Although actions are usually called after the render is
finished, in onClick handlers, etc.

Or maybe I could do this with Context. I'm just really tired of prop-drilling
all these action dispatch functions down to my components. There must be a
better way to automate all of the boilerplate with actions and reducers, even
if it's a Babel plugin.

~~~
acemarke
Hi, I'm a Redux maintainer. If you've got some suggestions on how we can
improve the API and usage, please file an issue!

I'm currently looking at revamping our WIP React-Redux v6 branches to use
hooks internally. Looks really promising so far, but I'll have to keep playing
with it and see how it turns out.

Our goal at the moment is to publish React-Redux v6 that is basically API-
compatible with v5, and then open things up to discussion about potential
alternative API approaches for a future v7.

~~~
nathan_f77
Hi, thanks for your reply! I've had a look at some of the higher-level
abstractions for Redux [1], but none of them really appealed to me. I'm just
looking for something magical and opinionated so that I can write less code,
so I might even try to write my own abstraction. I want to see if it's
possible to automatically generate actions and action creators just based on
the reducer. Maybe a special way of writing reducers, or maybe leverage the
type system and write a babel plugin.

[1] [https://redux.js.org/introduction/ecosystem#higher-level-
abs...](https://redux.js.org/introduction/ecosystem#higher-level-abstractions)

~~~
acemarke
Funny you should mention that :)

There's a lot of existing libraries out there that will indeed generate action
creators, reducers, etc (see my Redux addons list [0] for examples).

One of the most interesting ones I've seen is Eric Elliott's `autodux` project
[1], which does some clever bits of handling inside a `createSlice()`
function.

Earlier this year, I put together a new project called `redux-starter-kit`]
[2]. Its goal is to simplify several common use cases with Redux usage,
including store setup, reducer definitions and immutable update logic, and
default behavior out of the box. While we don't plan to add these things to
the Redux core itself, `redux-starter-kit` is an official Redux-branded
library, and we're going to start encouraging that people use it in most
situations.

We just added a `createSlice` function to `redux-starter-kit`, based on the
`autodux` approach. I'd encourage you to try it out, as it does _exactly_ what
you're asking for. I'd also really appreciate some feedback on how well it
works, and any additional ideas for things the starter kit should include!

[0] [https://github.com/markerikson/redux-ecosystem-
links](https://github.com/markerikson/redux-ecosystem-links)

[1]
[https://github.com/ericelliott/autodux](https://github.com/ericelliott/autodux)

[2] [https://github.com/reduxjs/redux-starter-
kit](https://github.com/reduxjs/redux-starter-kit)

~~~
nathan_f77
autodux looks amazing, thanks for the link! I hadn't seen that before, and
that's exactly what I'm looking for. Looks like there will be a bit of work to
add support for Flow and Immutable.js, but I might look into that.

redux-starter-kit looks great too!

~~~
acemarke
Sure. Also, just as an FYI, because a large number of people aren't aware this
is possible: you can pass an object full of action creators to `connect`
instead of a `mapDispatch` function. This simplifies the use of `connect`,
like:

    
    
        export default connect(mapState, {addTodo, toggleTodo})(TodoList);
    

We're about to add a whole big section on dispatching and action creators to
our new React-Redux docs site at [https://react-redux.js.org](https://react-
redux.js.org) \- keep an eye out for that. Until then, check out Dave Ceddia's
post at [https://daveceddia.com/redux-mapdispatchtoprops-object-
form/](https://daveceddia.com/redux-mapdispatchtoprops-object-form/) for an
explanation.

------
WorldMaker
Why not support Hooks _in_ classes as well? The motivation is correct in that
Hooks can help separate intertwined concerns that are currently mingled in the
lifecycle calls. There seems a good usefulness in allowing the same cross-
cutting inside classes as well as functions.

It would also presumably help avoid a "fork-the-world" situation where
projects eventually find themselves having to maintain _both_ HOCs and Custom
Hooks side-by-side permanently as the userbase forks camps between the two.
Potentially causing a maintenance hazard.

Certainly you can use one from the other one in component nesting, but
particularly in cases where maybe a class has an inconveniently complex
structure today, being able to refactor say all the state handling code to use
hooks without having to refactor all of the side-effect handling code at the
same time could be crucial for some projects in adopting Hooks.

------
eknkc
I’d say the useState hook should receive a name parameter first and not depend
on the call order. That way one can do branching, loops etc. This way it feels
like too much magic.

~~~
bnjmn
You're not alone!
[https://github.com/reactjs/rfcs/pull/68#issuecomment-4331815...](https://github.com/reactjs/rfcs/pull/68#issuecomment-433181520)

------
lacker
This looks like a nice but not enormous improvement to React.

First, I really like how these hooks are optional. You can still use the
current class-based mechanisms wherever you want. Existing code will keep
working the exact same way.

For the specific hooks they provide:

`useState` seems like a slight improvement over using `this.state`, at least
for simpler use cases. You save about 5 lines of object-oriented setup, which
is nice. You also avoid scattering your code all over the place - you can now
initialize your state variables in the same place you are using them. The only
downside I can see is that if your initial state is constructed in a
complicated way, `useState` doesn't seem to make it easy to do that only once.
When you state is just initialized as 0 or null it's fine.

`useEffect` looks a little confusing because it is passing a bunch of
anonymous functions around. It seems like a slight improvement if you have a
lot of side effects that need cleanup, because you can put the code in one
place instead of several different functions.

Hard to say how useful custom hooks will be. It might be easier now to put
functionality that uses state in third-party libraries. For example, this
`useDragGesture` hook:
[https://twitter.com/grabbou/status/1055521332031512576](https://twitter.com/grabbou/status/1055521332031512576)

The last thing that seems clear is that React embracing more of a "functional
programming" direction. I think some people will like this and some won't. The
nice thing is that you don't have to go all one way or the other - this change
seems like it is really about making all of React's features available if you
do want a functional programming style, since all of these features continue
to exist in an object-oriented style.

~~~
wichert
I can see the benefit being enormous if you use typescript. Currently it is
often a struggle to come up with the magic combination of generic parameters
and HoC ordering to make things work, which might still fail if your HoC has
an incomplete typing specification. Using a couple of very simple easily typed
functions makes things much easier to reason about and to specify correctly.

~~~
mhink
This was one of the first things I thought about when I read the docs. This is
primarily meant to replace render props and HOCs, which solve a legitimate
problem but are a royal PITA to use, especially with Typescript.

This is going to make it about a million times easier to use Typescript with
React.

------
coltonv
I have some troubles with the state hook. It may look nice to a novice
developer, but when I look at it I just see confusing magic. I read what's
happening and I just say wait, there's no closure or class here, how this
state is stored is completely hidden from me.

I can see uses for the other types of hooks, but the state hook seems like it
would be much better served with an HOC like Redux's connectToStore, which
would be concise and non-magical.

~~~
dvlsg
I agree. Something about it just doesn't feel right to me. Like state is
stored in a global singleton somewhere.

Any of the examples touch on testing components using hooks? Any chance using
the same component across multiple tests would result in state collisions?
Especially when testing something asynchronous?

------
manigandham
This looks like unnecessary magic. Classes are a core programming concept and
this seems to be trying to get JS devs who didn't deal with them before to try
and learn something else, while being completely non-transferable to any other
language.

Making the built-in state management functions simpler would be better, as
well as using newer JS constructs like decorators (aka attributes) to wire
things up declaratively. MobX has been leading the way here for awhile with a
very smooth dev UX that's even better than this Hooks proposal.

~~~
omegaworks
>Classes are a core programming concept

While I don't disagree with this, classes in their current incarnation were
shoehorned onto Javascript's prototype-based object inheritance mechanism
relatively recently. Javascript classes have enough idiosyncratic behavior
that half of what you learn is essentially one-off, inapplicable elsewhere.

As mentioned in the "motivation" section[1], binding to the `this` pointer of
the surrounding class efficiently in every context is not a simple
proposition. The naive way to do it introduces a bug (`this` ends up pointing
at the component passed the callback instead of the class) or creates
unnecessary closure instantiation on every rendering frame.

1\. [https://babeljs.io/docs/en/babel-plugin-proposal-class-
prope...](https://babeljs.io/docs/en/babel-plugin-proposal-class-properties)

------
acconrad
A demonstration of Hooks is live right now at ReactConf and looks _very_ cool:
[https://www.youtube.com/watch?v=kz3nVya45uQ](https://www.youtube.com/watch?v=kz3nVya45uQ)
(go back about 1.5 hrs into the past to see the start of the demo).

~~~
ggreer
Dan Abramov's talk starts 39 minutes into the livestream:
[https://www.youtube.com/watch?v=kz3nVya45uQ&t=39m](https://www.youtube.com/watch?v=kz3nVya45uQ&t=39m)

If you like live coding demos, he also gave a talk at JSConf Iceland where he
showed off some future React features, such as asynchronous rendering:
[https://www.youtube.com/watch?v=nLF0n9SACd4](https://www.youtube.com/watch?v=nLF0n9SACd4)

------
philosopherlawr
This document give me tinglings. Something about how the hooks just click with
me and I can see how the web changes with WebAssembly and multiple compile
targets (native, desktop, etc.), this will make our lives easier.

------
sergiotapia
So adding class lifecycle events to functional components? Why not just use a
class?

The beauty of the functional components is that immediately you know there's
ZERO state in here. It's just rendering markup based on input.

Now there's more to look out for given this `hook` thing. I don't like it.

~~~
markmark
This is an excellent point, not sure why you've been voted down. So now
functional components can't be guaranteed to maintain their best property?
Weird.

------
pcmaffey
I think this is a really positive solution to creating a streamlined
functional api.

However, in its simplicity (and hidden magic), I fear that it won't encourage
junior devs to understand what's actually going on, and thus may lead to bad
code (eg monster components with lots of side-effects running on render).

In a way, this reminds me of MeteorJS, which was awesome for new devs getting
up to speed with a powerful JS environment under the hood. However, by
internalizing much of that power, it became too closed off, too difficult to
build and compose new patterns around. And is now mostly irrelevant. Not
saying that's React's future (I'm all-in on React and excited for this), just
a concern / thought.

------
baddox
This is interesting. I'll have to spend some time mulling over this before the
benefits sink in. It seems like a much more confusing and less composable API
than recompose, which is how I add state, lifecycle, and other React class
features to functional components. I've been completely avoiding React classes
for a while now and using stateless components with recompose for over a year
now, and I find it to be a wonderful architecture for component testability
and reusability.

[https://github.com/acdlite/recompose/blob/master/docs/API.md](https://github.com/acdlite/recompose/blob/master/docs/API.md)

~~~
mcphage
The author of recompose just end of life'd it today in favor of Hooks. Read
his comment on the top of the recompose readme.

~~~
baddox
Still, I'll be looking into the hooks pattern and determining how it will work
for my projects and especially how easy it will be to port my large number of
reusable HOCs from recompose to React hooks.

------
Karupan
I absolutely fell in love with React when I switched over from Angular many
years ago. Loved the simplicity of the API and how you had to be explicit
about everything. Over the years, I've seen React start adding a lot of
"optional" APIs which increase the surface area anyway. This made me explore
other options and now that I've started doing some Elm, I feel it's so much
easier to reason with.

I guess this is the natural progression of frameworks. What was once simple
will get complex until the next thing comes around.

------
nine_k
Well, okay. Preact exists. Even mithril.js isn't completely dead.

Sad, though. A framework can afford a lot of technical debt, but adding more
conceptual debt, like React was doing recently, seems to me like a road to
oblivion^W legacy status. Features that lack clarity and come bundled with
footguns tax developer's brain resources, and increase the rate of errors.
These are some of the most expensive resources in IT, and fighting errors
lengthens time to market.

~~~
brlewis
> Even mithril.js isn't completely dead.

That's a rather un-generous description of a framework under active
development with an active community.

~~~
nine_k
A lot of code is 1-2 years old.

Though I'm happy that mitrhil.js lives and is being developed (not just
maintained). I only wish it wider adoption.

The "not completely dead" was meant to be somehow tongue-in-cheek.

~~~
cmx66
v2.0 is coming. Breaking changes are minor stuff. Migration of my very large
app took me about an hour. The API of mithril is pretty much settled, which
IMO is a good thing. We even plan to remove stuff for next major. Simplicity
is key.

------
zawerf
This is marketed as a proposal and a RFC, but it's already in React
v16.7.0-alpha.

If it turns out to be a bad idea (hypothetically speaking, I haven't read the
article yet so I don't know), will it be backed out?

Wouldn't it make more sense for it to be versioned as an experimental
fork/branch instead?

~~~
sophiebits
Yes, if we decide not to include this we will definitely back it out. However
we’re excited and hoping that we can agree on something everyone will love.

We could use a separate branch but in practice we prefer to use feature flags
for development; we find it easier to manage. Once we reach a definitive
conclusion on whether to include it, we’ll remove the feature flag.

------
lexicality
Oh great. Another React feature that relies on creating anonymous functions
every time your component renders.

I presume this is now adequately fast in the various JITs in use, because I
seem to remember this being one of the major bottlenecks React developers were
instructed to avoid doing at all costs.

~~~
dceddia
Yeah, they answer this in the FAQ too.

> In modern browsers, the raw performance of closures compared to classes
> doesn’t differ significantly except in extreme scenarios.

[https://reactjs.org/docs/hooks-faq.html#are-hooks-slow-
becau...](https://reactjs.org/docs/hooks-faq.html#are-hooks-slow-because-of-
creating-functions-in-render)

------
dfabulich
I don't want useState to magically determine which state to use via call
ordering. I want to pass a unique ID string to useState and have that
determine which state I want.

Order-based management could then be opt-in, and based on a non-magical ID-
based system.

------
see-dante
I don't dig what they're doing, but I do kind of like the idea of a
deconstructed getter/setter:

[ get, set ] = getterSetter(defaultValue)

as a wrapper around some stateful, immutable value (mutating the result of the
get won't be tracked, that is)

~~~
dceddia
That's pretty much what useState does. (or maybe you were already saying you
liked that -- sorry, if that's what you meant) The only difference being that
the "getter" has already been "executed" in a way: useState returns a value
and a setter. Changing the value won't get tracked, and a call to the setter
will overwrite the old value and re-render.

~~~
see-dante
Yeah -- I'm saying it's dubious that there's magic here "doing the setState
queue for you" \-- notice the function call isn't bound and there's no passing
of "this", so it's gotta' got some magic under the hood with some global
context.

I do, however, like the concept for the react style of render -- being able to
grab a getter/setter from that is awesome. They can remove the magic by simply
doing:

const [getter, setter] = this.useState(...)

~~~
acemarke
It's nothing more than React already knowing exactly _which_ component it's
working on rendering. See my other comment here:
[https://news.ycombinator.com/item?id=18306957](https://news.ycombinator.com/item?id=18306957)

------
Androider
No sir, I don't like it :/ I don't see a simple API, I see a completely magic
black box that is going to chew up my fingers if I decide to put my hand in
it.

Don't fight the language! JS is a still an evolving language, class properties
are at Stage 3 draft, and have effectively been usable for years already. I
feel the verbosity argument against classes is complete bunk.

When you write "TLDR: There are no plans to remove classes from React...
Crucially, Hooks work side-by-side with existing code so you can adopt them
gradually... Finally, there is no rush to migrate to Hooks." it doesn't give
me the warm and fuzzies, quite the opposite. I can feel the momentum is going
to shift to the new hotness and a completely different way of doing things and
I'm not sure I want to go where you're heading. Until the next shiny thing.

I wish React would stop adding to the core library. I strongly feel most of
the innovation should be happening in libraries surrounding it, even if
they're first party libraries, with the core being much slower to change. A
good reason to change the core would be taking advantage of new standardized
JS features in the future, or (minimally breaking) changes to support big
ideas like async rendering. Changing the fundamental way you write React code
because "classes are confusing" is just a terrible reason!

------
chrisweekly
Someone much smarter than me said something like "good magic decomposes into
sane primitives". Jury's still out on whether Hooks and "useState" qualify.

------
techsin101
I wish they'd work on global event based system to pass state, like redux but
built in and steam line it for all use cases like promises. React state
propagation sucks.. what Vue is doing with events is basically imitating redux
but easier. Context API is very lacking and similar boilerplate as of redux

------
iEchoic
> Hooks allow you to reuse stateful logic without changing your component
> hierarchy.

Why haven't ES7 decorators been more widely adopted for this? We've been using
them for over a year for this purpose now and they've ended up being far
cleaner, more powerful, and more composable than the proposed interface.

~~~
styfle
Decorators haven't been adopted because they are not specced or shipped.

There is no decorator feature in the ES7 (ES2016) spec.

However, there is a proposal for decorators that it is not finalized yet.

[https://github.com/tc39/proposal-
decorators](https://github.com/tc39/proposal-decorators)

------
theothershoe
On the positive side hooks provide a lot of options for declarative
abstractions. I expect that to a large extent the built-in hooks will be used
as building blocks for new libraries. I think it is likely that this will
outweigh the negatives.

On the other hand, hooks rely on hidden side effects so that each hook
invocation returns something different depending on which component instance
in the component tree is being rendered when the hook is called, and the
number of times the hook has already been called while rendering that
instance. This introduces semantics that are unlike anything I know of in the
language. A redditor, u/hardwaregeek, pointed out that hooks behave kinda like
a state monad, albeit emulated with imperative side-effects.

------
Felz
I really wish React wouldn't add more state handling, because it's never been
particularly good. I use MobX and loathe the overcomplication of stuff like
e.g. Redux. Hooks look like a misguided attempt at addressing React's lack of
automatic reactivity.

------
KuhlMensch
Nice. Its attending to the same *intention as
[https://github.com/acdlite/recompose](https://github.com/acdlite/recompose)
but without as much boilerplate (and without HOC which carry some drawbacks)

------
ilaksh
I'm actually most comfortable with object-oriented programming since I started
doing that 26 years ago. However, this simplifies the lifecycle business
somewhat and results in a slightly cleaner JavaScript syntax than the class
based way in my opinion.

------
beders
Another clear signal that React alone isn't enough and should be used only as
renderer.

Now get off my lawn while I tend to my rum*

*[https://github.com/tonsky/rum](https://github.com/tonsky/rum)

------
ajcodez
Very cool feature. It reminds me of MobX where changing the observable value
auto queues a render. It’s super productive. With hooks calling the setter
auto queues a render too.

I’ve had a few embarrassing bugs in the past where the page route changes but
it’s the same component so it doesn’t call componentDidMount and doesn’t fetch
the new data. It looks like hooks default to fetching data too often instead
of not enough which feels correct. Instead of users wondering why the page is
broken your team is wondering why the server is getting 1000x more requests.

------
oldboyFX
This is pretty interesting but it's not immediately obvious whether it's an
improvement over the current system.

Looks like one of those things you have to use for a couple of days before
coming to a conclusion.

------
tropshop
Front-end devs need to first master the vanilla tools, then reach for the
frameworks once they understand the why.

I'd like to see a build tool that focuses on plain HTML, CSS, and ES6 modules.
It takes the input .html file, parses the <script type="module"> elements, and
statically analyzes the code to polyfill and re-write output for specified
browser compatibility.

I think part of the problem is that the intro tutorials for the fully loaded
frameworks look so much simpler at a glance than trying to wrangle something
on your own.

Any ideas for youmightnotneedreact.com?

------
Illniyar
On the one hand I'm not sure if I like how this paradigm hides it's
implementation so thoroughly - abstractions whose core is invisible to the
developer is how simple libraries turn into monstrosities.

On the other hand, this will finally make functional component viable, and
actually let us get mixin functionality.

I think it's a good idea, maybe even a great idea after a few adjustments, but
it doesn't really belong in core IMO.

------
pastelsky
I like how it makes it possible to re-use behaviour among components, but I
also really liked how classes encouraged structure and readability.

My hunch is it's only a matter of time before someone creates a helper that
would enable `useState` to take complex objects rather than calling it
multiple times.

Also, custom hooks seem almost too powerful - easy to build multiple
abstraction layers and make the API feel magical at the point of use.

~~~
mhink
> My hunch is it's only a matter of time before someone creates a helper that
> would enable `useState` to take complex objects rather than calling it
> multiple times.

You can already do that, although it's not _exactly_ the same as setState in a
class (states aren't merged together... but if you really wanted to, it'd be
about five lines to implement a custom hook)

    
    
        const [state, setState] = useState({
          foo: "123",
          bar: "abc",
        });
    
        function updateBar(nextBar) {
          setState({ ...state, bar: nextBar });
        }

------
k__
Cool idea, feels a bit like observables, especially the unsunscription via
returned callback.

The call order thing seems odd. Don't know how to sell this to people.

~~~
cormacrelf
Angular's problem with observables is being completely mismatched with
component state. You have to unsubscribe stuff manually all the time with any
complex app, and it's a nightmare to debug when you've forgotten. You can use
`@ngrx/utils` with class-property attributes now, but it's still weird and not
always applicable and like most angular things, couldn't be coded by a newbie
as it relies on the vomit-worthy-but-kinda-works metadata system.

AFAICT, with state+event hooks you could just write a function in a few lines
to subscribe to an observable you pass to it, setState on each new value, and
unsubscribe, and then use it everywhere.

(Edit: yes, of course there is the | async pipe. Not everything is in the
template though.)

~~~
k__
I always had the feeling Cycle.js is the better observable framework.

------
maaaats
> _React doesn’t offer a way to “attach” reusable behavior to a component_

I know the angular resentment here is high, but some things Angular 1 got
right. Directives added as attributes to another component was very powerful
and allowed this in better ways than HOCs in React. Im looking forward to try
this out.

~~~
jf-
I think the Angular resentment is a little behind the times, the days of
Angularjs 1 and the beta versions of Angular 2 are behind us. The new Angular
is worth a look, especially if react is now having various extras bolted on ad
hoc.

~~~
markmark
> the days of Angularjs 1 and the beta versions of Angular 2 are behind us

There is still a _heap_ of Angular 1 code out there since the 1 -> 2 move
basically meant you couldn't upgrade without a full rewrite. Both my last two
jobs have involved re-writing Angular 1 apps.

~~~
jf-
Sure, there are lots of Angular 1 apps still in production, as there will be
with most legacy systems. My point is that Angular 1 is no longer the current
version, and with the latest version it’s much better to use. I think the main
issue is the learning curve, but you just have to bite the bullet.

------
yen223
Correct me if I'm wrong - hooks are essentially algebraic effect handlers but
implemented in JS?

If so, colour me excited!

------
sktrdie
A similar approach was proposed here about a month ago:
[https://twitter.com/alexeyraspopov/status/104570630502400819...](https://twitter.com/alexeyraspopov/status/1045706305024008192)

------
salvoravida
My 2c on the hooks cause: [https://github.com/salvoravida/react-class-
hooks](https://github.com/salvoravida/react-class-hooks)

Use Custom Hooks with React Class Components. Compatible React >= 16.0.0

------
pier25
Since I started using Mobx I'm actually enjoying using React purely as a
rendering library and user input. No Redux, and certainly no setState.

I really don't see the point in hooks.

------
linkmotif
> Motivation

> It’s hard to reuse stateful logic between components

Recompose kind of solves this. Why add this to the core API? What am I
missing?

~~~
mcphage
Read the comment from today on the top of the recompose readme.

~~~
linkmotif
Well then... thank you.

For reference, it says:

> A Note from the Author (acdlite, Oct 25 2018): Hi! I created Recompose about
> three years ago. About a year after that, I joined the React team. Today, we
> announced a proposal for Hooks. Hooks solves all the problems I attempted to
> address with Recompose three years ago, and more on top of that. I will be
> discontinuing active maintenance of this package (excluding perhaps bugfixes
> or patches for compatibility with future React releases), and recommending
> that people use Hooks instead. Your existing code with Recompose will still
> work, just don't expect any new features. Thank you so, so much to @wuct and
> @istarkov for their heroic work maintaining Recompose over the last few
> years.

------
crooked-v
Maybe it's just me, but this feels a lot like just reinventing mixins, except
more confusing to understand.

------
fiatjaf
Everybody is complaining. I like this. Classes should be abolished, though.
And perhaps this should be published as a different React version, like "React
Classless" or whatever.

Classes with special method names, manual binding of methods, mixed ways of
doing things (inlining a function or defining it separatedly?) are a mess
already, and this will arguably add more to the mess, but the intentions are
good.

------
sktrdie
Is it just a syntactical difference or is there something more fundamental
that I'm missing here?

~~~
acemarke
It's a huge difference, and yet also the same thing.

It's the same concepts of props, state, context, and lifecycle behavior as
before.

It's just that now you can do it in function components, not just class
components, and the APIs let you handle things without having to have
additional levels of wrapper components and without the complexity of class-
related gotchas.

~~~
tinalumfoil
Can someone give me an example where hooks replace a wrapper? All the examples
I see can be replaced with a single class, albeit a couple more lines of code.

~~~
acemarke
Context is a great example. Right now, each `<MyContext.Consumer>` instance
shows up as another level of wrapping in the devtools, _and_ requires
indentation/hierarchy in the render methods. With `const someValue =
useContext(MyContext)`, there's no actual component being used, so both the
component hierarchy and the render code itself is flatter.

------
ihuman
How is this different using from Javascript's function prototypes to add
functions to an object?

------
devit
Why aren't these functions methods on "this" instead of magic freestanding
functions?

~~~
dceddia
Hooks only work in function components, so there's no "this" (at least, not
one that React owns...).

~~~
devit
Couldn't it just bind "this" to whatever object it uses to store component
data?

------
rhacker
This looks freaking AWESOME.

------
pcmaffey
Is there a proposed timeline for releasing this on master?

------
wetpaws
React is starting to turn from a novel, but essentially simple idea into a
clusterfuck mess.

~~~
rhacker
I feel like Redux was a clusterfuck mess and this is the cleanup. Excuse the
language.

Edit:

Expanding on this and why (I think) this solution is cleaner:

* In redux you ended up with pointless constant piles of strings that are the named actions. Totally useless in a JS world where a function that IS an action can take up that mantle.

* While reducers are a good way to make state consistent, using redux for state management when you actually don't have 17 different producers and 1 consumer it's major overkill. Most of the time you actually have 1 or 2 event (and value changing) producers and MANY consumers on the screen at one time.

* When you DO need a reducer, instead of making that the norm, this new hook library does provide a useReducer function that works exactly like that- and guess what? NO STRING CONSTANTS YAY.

I think the only downside I can think of is TTDebugging might be complicated
to create under this dome, but was the same issue for stateful classes. That
being said, it might be more possible now that the control is placed in a
single feature area.

~~~
oldboyFX
People use Redux way too often and think of features like time travel as nice-
to-haves, when in reality they're the main reason why you'd want to use Redux
in the first place.

Using Redux just to simply set and get data on every page is an overkill.

For the majority of applications making API calls directly from the component
and storing data in the comp state is the way to go.

This is coming from someone who used redux excessively in the past.

~~~
CuriouslyC
What do you do when you want to update state in other places in response to a
change in a component? How about if you want to make your component's state
persistent (particularly when the component is external to your project)?
Also, what do you do to generate state dumps for error reporting?

~~~
oldboyFX
> What do you do when you want to update state in other places in response to
> a change in a component?

In 90% of the cases one of the parent components. Sometimes redux when the
component tree goes super deep, or for things such as currentUser.

> How about if you want to make your component's state persistent
> (particularly when the component is external to your project)

What do you mean? Give me an example.

> Also, what do you do to generate state dumps for error reporting?

I don't generate state dumps for error reporting.

------
nahfamwegood
Man, they really ruined React.

I remember when it was AWESOME, back in 2013 when only me and like 10 people
were using it and the API was simple because it was brand new.

ugh, now I have to read a bit more and have all these new features. I'm an
engineer, I only like things when they're simple.

I wish it was back in the simpler days when JQUERY was hot. Man, miss those
days for sure.

------
falconmick
If you don't want magic don't use a framework

------
regularfry
How the hell do you test the damn things?

~~~
coldtea
Like you'd test any other component?

[https://reactjs.org/docs/hooks-faq.html#how-to-test-
componen...](https://reactjs.org/docs/hooks-faq.html#how-to-test-components-
that-use-hooks)

What exactly looks difficult about testing them? Existing components already
carry state and use lifecycle methods...

------
john92
ddd

