
I love React Hooks - vijayst
https://vijayt.com/post/react-nugget-2-why-do-i-love-react-hooks/
======
kristiandupont
Contrary to some commenters here, I think React is just about the best thing
that has happened to UI programming in recent memory.

Everything I tried before it (jQuery, Backbone, Knockout, Angular, Meteor
(with Handlebars)) felt like it fell short or, in the case of the databinding-
oriented ones, like a broken abstraction. I get a similar feeling when looking
at Vue though I have no experience so I might be wrong.

I too am a bit skeptical about hooks making what looks like pure functions act
like stateful ones. I am not using hooks yet but besides from Dan Abramovs
excellent articles about their rationale, I think I will look at them like a
new paradigm, only using a syntax that we know from something else. In fact, I
wouldn't be surprised if I some time in the future will be using React to
write state machines for something that doesn't have anything to do with UI,
where "rendering" composes state related to something else entirely. I could
see hooks being a game changer here.

~~~
shubhamjain
One reason I love Vue over React is how beginner friendly it is. You can't
make a "Hello World" app in React without getting bombarded with concepts and
terms—states, props, JSX, stateful components. Just look that the "Getting
Started" example of Vue [1] and compare it React's [2]. You don't need
anything more than a notepad to get the first example running.

Progressing down Vue, you realize how they have tried to prioritize
convenience. For example, using "v-on:keyup.enter" you can map an action to
"Enter" key without writing code for handling that key.

I liked the React's approach but it seems its focus is on purity of
abstractions than convenience. Don't even get me started on Redux which is
epitome of needless complexity—containers, reducers, event emitters? Was all
that really needed?

Note: I have no idea how Vue fares when code base is huge, but my intial
impression makes me feel it's far better choice than React.

[1]: [https://vuejs.org/v2/guide/#Declarative-
Rendering](https://vuejs.org/v2/guide/#Declarative-Rendering) [2]:
[https://reactjs.org/tutorial/tutorial.html](https://reactjs.org/tutorial/tutorial.html)

~~~
danabramov
_> Just look that the "Getting Started" example of Vue [1] and compare it
React's [2]._

Thanks for feedback!

The linked React guide is intended to be a pretty comprehensive tutorial — not
a getting started guide in the same sense. I wouldn’t say they’re comparable
in how much about either of them teaches you about using a library. Maybe it’s
not obvious from the wording.

If you do want a simple “getting started” guide that doesn’t require any
tools, it’s right here:

[https://reactjs.org/docs/add-react-to-a-
website.html](https://reactjs.org/docs/add-react-to-a-website.html)

And you can progressively learn all important concepts starting from here:

[https://reactjs.org/docs/hello-world.html](https://reactjs.org/docs/hello-
world.html)

Another common destination is this guide, which matches the Vue one in purpose
a bit more closely: [https://reactjs.org/docs/thinking-in-
react.html](https://reactjs.org/docs/thinking-in-react.html)

The “get started” link on the React page links to resources for people with
different experience levels:

[https://reactjs.org/docs/getting-
started.html](https://reactjs.org/docs/getting-started.html)

Hope that helps!

~~~
shubhamjain
Fair enough. These seem much better for starting out. However, the progression
in Vue's guide is much better thought out.

Step 1: Get a simple "Hello world" running.

Step 2: Get something dynamic on screen.

Step 3: A simple if statement.

Step 4: A loop.

Step 5: User Input.

By the end of the guide, I know all there is to know to make a very simple
interactive component.

~~~
danabramov
Thanks for feedback. I do think the “main concepts” guide goes in roughly the
same order but I agree there could be a more condensed single-page version of
it. We’ll keep it in mind for the future!

------
lioeters
After reading numerous articles (starting with the docs), I'm still not
convinced, and will not be using React Hooks any time soon. Some of the things
I do not love:

\- Magic, in the unfavorable sense: if hooks were implemented in an indepedent
library, just hearing that they "must be called in the same order every time"
and "cannot be used inside conditional statements" should make anyone wary.

\- Scope creep: if anything, I wish React focused on _reducing_ its size and
API surface.

\- Entanglement: related to the point above, the goals of hooks would have
been better served with a separate, tiny library that doesn't need to know
anything about React, and usable anywhere else, with plain functions that can
be tested or reused independently.

Well, the topic deserves a deeper criticism than "it feels wrong", so I hope
someone can write a worthy article called "Why I Do Not Love React Hooks",
with an example of a better, alternative solution.

I hesitate to bring up a cliché, but it's starting to feel like React is the
new jQuery. I'm already trying to anticipate what comes after React, in which
case I want my code to depend on the smallest possible API surface area.

But then again, maybe it's my wishful thinking that we would move towards
"universal components" (using dependency injection to pass in React or other
view renderers like Web Components). Since much of the JS ecosystem seems to
be going "all in" on React, perhaps I should surrender to its current. As long
as I continue to use React, it looks like there's no escape from its hooks..

EDIT: I should add that the above is just my opinion at the moment, and I'm
open to changing my mind. Who knows, I may unwillingly start using them (since
everyone else seems to be), and come to love hooks after all.

~~~
xrd
1\. Isn't React sort-of magic to begin with?

2\. Don't hooks remove the need for redux, etc.? Meaning, don't hooks
radically reduce the amount of libraries you need to know about?

3\. I prefer to use pure React and not have to choose between Redux, Flux,
Mobx etc. And, then do I need to use redux-thunk, etc?

I actually really like the progression towards hooks. I think the articles
from the core team (like Dan Abramov) have been well written, explaining not
just the how but the why, and it feels like hooks serve to make things simpler
and more readable. Yes, you have to throw away a lot of things you spent time
learning, but I'm not sad to see anything go away that hooks now handles.

~~~
Axnyff
I feel like if hooks remove the need for redux for you, you actually never
needed redux in the first place.

~~~
omeid2
What Redux brings to the table is separation of Data from Components, it is
not uncommon to use the same data point (user profile, user organization/s, et
al) in various components. Moving this to component states either requires a
lot of prop passing or duplication (api calls!), short of using Context, which
is kind of Redux-ish all over again.

------
_hardwaregeek
While I do like the idea of more functional components, I don't think hooks
are the answer. The reason I like more functional components is because I want
to keep components small, stateless and dumb. Hooks encourage people to write
more functional components, but I'm not sure that they'll encourage people to
write functional components properly. Instead they'll just transfer the anti-
patterns they're writing in class components to anti-patterns in functional
components. For instance, I could see people writing large functional
components with big globs of state and side effects.

The real issue which I want to see solved is getting people to remove business
logic from React. I see components loaded to the gills with data fetching and
overly complicated async rendering schemes. Personally I try to keep my React
components extremely dumb. Instead I try to keep most of the business logic on
the server side when possible, and in Redux otherwise. But even that's not
great. Redux is fundamentally a data store, not a business logic library.
Trying to do complicated logic with selectors/actions is a nightmare. I
suppose that's why front end frameworks like Angular and Ember are popular.
React ultimately is a view library and yet it provides no good option for the
business logic.

~~~
underwater
Fighting advancements because they _could_ be misused is a battle you cannot
win. If your team is going to misuse features because they simply exist then
you need to address the root cause — your team — not the library.

------
denverkarma
How is it that React gets celebrated for “solving” problems that React created
in the first place?

The entire paradigm of React keeps changing as each pervious iteration proves
to be “messy” or “over complicated.” createClass? Nah that’s obsolete. Mixins
and HOC - oh wait, bad idea, hooks to the rescue!

At what point do people start to call BS and say you shouldn’t build around a
framework that needs to be reinvented every year or two?

~~~
sophiebits
(I worked on React.) Many people have adopted React and are happy with it,
evidently because they believe the problems it creates are minor compared to
the problems it fixes.

It’s rather reasonable for them to be excited about a new version that keeps
(or improves!) the good parts while having fewer tradeoffs.

~~~
jen729w
React is _amazing_. I'm teaching myself JS — started October '17 — and I've
gone through a few iterations of my little project as I learn more.

\- Vanilla JS: it _works_ , but holy moly it looks bad and the amount of code
I have to write to do even basic stuff really really hurts my brain. (Actually
what am I talking about, it never got close to "working" before I moved on
to...)

\- jQuery/Node: ooh, this is better. But still, doing stuff takes _ages_.

\- React: OH MY GOD WHAT IS THIS HEAVEN.

People will say that "people like me" shouldn't be writing web apps if we
don't know what we're doing. To them I say, screw you. These tools enable us
to do things that would never have been possible.

Thank you from the bottom of my heart for doing whatever it is that you did.
:-)

~~~
dnautics
I was initially resistant to a lot of react, for example, jsx. However as a
backend dev (functional) I was very pleased when I could dive into react code
and reliably implement features as needed.

------
Azeralthefallen
Honestly i struggle when people argue that 'this' and class components are
complicated, and that hooks remove that complexity. Yet then i see people
composing together dozens of various hooks and HoC's to achieve the same
balance is beyond confusing.

Recently i was assigned a PR for a component (a login form) i wrote about a
two years ago which was a whole 300 lines. The person who wrote the PR also
took the time to make it "functional", which has now resulted in it being
split into almost a dozen different files. I don't find this cleaner or easier
to understand at all.

Current team i am on uses MobX, and Typescript for our app and frankly it is
painfully simple, and yet people keep arguing that we should drop mobx, and
switch to hooks and i don't see any benefit.

~~~
kabes
One part of the functional promise seems to be that if every piece of
functionality is small, isolated and easy to understand that the whole of the
application becomes easy to understand. However, I would agree that I often
find the opposite to be true when everything is scattered around in mini
functions over hundreds of files.

~~~
arkh
> One part of the functional promise seems to be that if every piece of
> functionality is small, isolated and easy to understand that the whole of
> the application becomes easy to understand.

This part is wrong. Your huge components are made of what? Small things.
Isolating all those small things just let you add more boilerplate and mental
load when trying to debug. To reduce complexity you have to remove code, not
move it around.

~~~
danabramov
I don’t think we promote isolating _every_ little thing. That would indeed be
counterproductive.

It’s more about _being able_ to reuse some stateful logic between components.
That’s the point of custom Hooks. There are pretty cool libraries existing
already. For example React Spring takes advantage of that programming model
for animations: [https://www.react-spring.io/docs/hooks/use-
spring](https://www.react-spring.io/docs/hooks/use-spring)

I tried to explain the motivation for Hooks here:

[https://medium.com/@dan_abramov/making-sense-of-react-
hooks-...](https://medium.com/@dan_abramov/making-sense-of-react-hooks-
fdbde8803889)

Hope it helps.

------
littlecranky67
Hooks are a big deal if you use TypeScript with React. Explicitly typing the
state is gone (it will be inferred by what you pass as initial value to
useState()). So is weird Partial<TState> typings when setting the initial
class state in the constructor or via this.setState().

And if you ever had to deal with correctly typing HOCs or render props you had
to dig very deep into conditional/mapped types in TS. With hooks this is
basically gone.

~~~
machiaweliczny
With classes you also don't have type state when using 'state = { ... }'.

I think hooks might be nice for data fetching when it comes to TS as it will
super easy to get typing.

I'm still not convinced by hooks though.

~~~
littlecranky67
Yes you do, you have to give the type of the state in the 'extends' clause:
'class MyComponent extends React.Component<TProps, TState> { ... }'. If you
omit TState, an empty object {} is assumed for state. And you have to specify
the type when updating the state via .setState(), because setState() auto-
patches/merges the state. So its fine to pass a Partial<TState> to setState.

With Hooks, the auto-patching goes away, so your call to setMyCustomState()
always requires an argument of type TState.

There are similar issues if you use the 'static defaultProps = { ... }' on a
class - you have to manually specify the type of defaultProps - often it is
Partial<TProps>

------
ronilan
> _With React Hooks, I do not need to deal with the messy “this” coding
> pattern of class components. And there are no three ways to write this
> code._

Yep. Now there are four.

I have no specific opinion about React hooks (or about love for that matter),
but “languages” with a simpler vocabulary do tend to have an advantage in the
long run.

------
Bahamut
Devs beware, hooks are not quite there yet it turns out.

You get warnings in jest about needing to use act from react-test-renderer if
you use async code to trigger state updates - the solution being recommended
currently is mock every promise with a synchronous version, which then litters
your app code with conditionals in many places for whether to use the mock or
real promises. At that point, you're much better off using Angular for writing
decent component/unit tests, where you don't have to fight with any async DOM
or JS api in order to write working tests, or pollute app code with test
specific branching logic since that is all handled at a single injection point
via the IoC container.

If you have promises, you're forced to bleed a isMounted type of flag into the
cleanup function scope in order to guard against promises attempting to
trigger state changes after the promise is complete with its async function
(i.e. data fetching).

These are two frustratingly painful dev ergnomoics situations that are
unsolved with hooks. Otherwise, I am happy with them, but these are major pain
points I have encountered with them so far, and given FB doesn't use promises
in their internal apps for the most part, I don't see them likely to put in
much work solving these problems unfortunately.

Disclaimer: I would love to put in some effort to solve these pain points with
design discussions & code, but unfortunately I cannot put in that work without
going through approval processes with 5+ people.

~~~
danabramov
_> given FB doesn't use promises in their internal apps for the most part, I
don't see them likely to put in much work solving these problems
unfortunately._

This is inaccurate.

The first problem has an issue tracking it
([https://github.com/facebook/react/issues/14769](https://github.com/facebook/react/issues/14769))
and even a pull request
([https://github.com/facebook/react/pull/14853](https://github.com/facebook/react/pull/14853)).
It’s barely been two weeks since the first release and we’ve been focusing on
fixing actual bugs as soon as possible. As I hope you can understand, warnings
in tests are a bit less critical and can wait behind production bugs. But
we’ll get back to fixing the warnings as soon as possible — maybe even this
week.

As for isMounted-like flag. This has nothing to do with Hooks. Classes need
exactly the same thing. If you forget it, you’ll likely have both the same
kind of warning, and possible race conditions from requests arriving out of
order. In longer term we’ll offer a much simpler data fetching integration
(read about Suspense) which doesn’t involve effects or lifecycles at all. I
think you’ll like it.

------
vmware505
I actually like classes and using "this". Maybe I just like Object Oriented
style. :)

~~~
sophiebits
OO style definitely feels more familiar to many people.

You may find Dan’s thread on this subject interesting though — he tries to
explain why neither plain classes nor plain functions are the best fit for
React:
[https://twitter.com/dan_abramov/status/1093694465917751298](https://twitter.com/dan_abramov/status/1093694465917751298).

~~~
hitekker
Truth be told, that twitter thread sounds more like a justification than an
explanation.

~~~
danabramov
Does this sound more like an explanation?
[https://news.ycombinator.com/item?id=19206401](https://news.ycombinator.com/item?id=19206401)

I’m happy to answer specific questions.

~~~
lugg
Sounds more like a bunch of excuses.

Why do I, a framework user, need hooks?

What problem do they solve for me?

If you can't answer that without talking about what react broke first I don't
think we we need whatever you're selling.

Added responses there too.

I feel like hooks are a solution to shit code that just needs a refactor.

This happens a lot in frameworks that try to please everyone all the time. You
give people of all experience levels the same feature set. It's no wonder at
least half your user base goes out back and shoots themselves in the foot.

If you want to fix this problem you need to remove flexibility. Not give them
yet another method to hurt themselves.

I'd start by splitting component concerns. MVC might be a good candidate.
React.fragment components tend to smell like fat models. Pure functions
basically views and connect code/prop/state mapping looks a lot like
controllers.

Fwiw this small UI component thing is originally what the MVC pattern was
intended for. The big laravel style classes we have today are a
misappropriation of the patterns name onto something that it shouldn't have.

~~~
danabramov
They give you the ability to reuse stateful logic between components. You’ll
need to be more specific about why it’s an “excuse” to you. Lots of people
seem to find this ability useful.

~~~
lugg
They're excuses because none of them involve explaining when, where and how
they are useful to a user.

They all basically say "framework needs it" or "we heard you like functions,
so now we're getting rid of classes and making everything functions, but you
still actually need classes and state and all that stuff so we're shoving
state into globally accessible static functions that you have to call in the
same order every time or things just won't work."

Like this whole thing is just absurd.

> They give you the ability to reuse stateful logic between components.

Stateful logic a code smell, we do not want this.

Redux actually gets this stuff correct - binding logic and effects to props
and state should be done outside of the presentation layer.

I would have just fixed the redux API so people stop shooting themselves in
the foot with it.

\--- In any case, thanks for your comments, this has given me a lot to think
about, I'm now wondering about how to replace useState with a prop named
state. I'm also wondering if bi-directional prop mutation would solve all this
cleanly - i.e. bind props instead of passing them, I think KnockoutJS did
something like this.

------
fastbmk
TL;DR

People who wish that progress would stop on jQuery & Rails - won't like React
Hooks either.

------
Matthias247
Calling classes messy isn’t really a strong argument. classes are one of the
valuable tools in a programmers toolbox. Emulating them via a bunch of
closures that act on shared state isn’t necessarily better.

~~~
dmitriid
Problem is, they are very messy in JS. They are a bad thin non-fitting
abstraction over JS prototypes.

People keep trying to fix them: [https://github.com/andreypopp/autobind-
decorator](https://github.com/andreypopp/autobind-decorator)

~~~
exogen
Not only that, but classes are at odds with advanced render scheduling like
React is moving towards (concurrency, prioritized rendering, context
switching, bailing out of renders, etc.).

With a class instance, what happens if you need to bail out of a render and
potentially restart it again later? The developer could have done literally
anything to their class instance the first time through. They could be
inheriting from anything and doing whatever they want to `this`. You can't
easily "restart" it from its original state, unless you made a perfect
snapshot, which is not easy with class instances – you'd need to perfectly
deep clone the prototype chain and such.

With functions and hooks on the other hand, there is no class instance or
prototype chain to worry about. All state (whether stored via useRef or
useState) is controlled by React – the actual object it gets stored on is
hidden from the developer. If React wants to ditch the "instance" it was
updating on the previous attempt and reuse the one it started with, it can do
that without worry.

It's the same reason "time travel" features are easier with more functional
approaches. Adhering to functional programming ideas pays off in the long run.

------
_pdp_
As a developer of a extremely large code-base written in Rect
([https://launchpad.secapps.com](https://launchpad.secapps.com) for reference
of the kind of apps we are talking about), I am not convinced that "Hooks"
solves anything in particular that it is not already solved through
decorators. We use decorators quite extensively, from assigning styles in a
way that does not force the component to re-render due to props changes, to
controlling the props themselves with onChange events and so on.

In my professional opinion, which is based on years spending time with react,
the typical gotchas in this framework are down to experience. Experienced
react, and more importantly js, developers will write better, more performant
code. This is applicable across the board regardless of the
framework/language. Hooks will not particularly remove this need nor will make
you a better programmer.

While hooks look functionally ok what worries me is that they will be subject
to a number of problems. For example, complex hooks/components might be
subject to memory leaks. With hooks, we are defining closures inside the
functional component which will be subject to having access to proceeding
scopes. This is an anti-pattern that we removed from our code-base by using
classes. The second problem is that your component will needlessly re-render
in those cases where the component is not entirely functional. This may not
seem like a problem in the simple examples seen thus far, but it will be with
more complex components as I've seen in my experience.

React is one of the best frameworks we have seen around so I am happy that we
keep pushing the boundaries but what worries is me is that the React team
seems to declare that they are moving towards components written with hooks
(not removing classes) which in my opinion is not based on solid evidence that
will amount to anything useful in particular.

Again, as far as I am concerned, hooks does not contribute to anything that we
are not solving in much better way and I doubt they will ever be used at all
as far as our code-based is concerned.

~~~
kilburn
While I don't disagree with you generally, this part

> The second problem is that your component will needlessly re-render in those
> cases where the component is not entirely functional.

is addressed by the react developers in the FAQ [1].

The answer wasn't obvious to me, so I made a toy example in CodeSandbox [2].
There are 3 counters that can be updated using 3 corresponding buttons. Each
counter uses a different approach:

1\. The "handler" counter uses "useState" \+ "inner function in the parent's
body". The corresponding button rerenders every time the parent rerenders
(i.e.: the problem you are highlighting)

2\. The "callback" counter uses "useState" \+ "useCallback" to memoize over
the counter's value. The button rerenders only when it is clicked (and hence
the counter it controls is updated).

3\. The "reducer" counter uses a react context to inject a "dispatch" function
that calls an out-of-parent reducer. The button never rerenders. The docs are
clearly pushing the reader towards this solution (albeit it is contrived for
very simple examples such as this one, I can see the benefits surpassing the
boilerplate overhead of reducers in more complex situations).

[1] [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)

[2] [https://codesandbox.io/s/r584lz2pom](https://codesandbox.io/s/r584lz2pom)

------
alangpierce
Part of the point of solutions #1 and #3 is that they pass in exactly the same
function on each render, so it's possible to avoid unnecessary rendering
further down by knowing that the props are the same as before. The hooks
solution will make a new handleChange closure each time, so it'll be a
different function. Is there are way with hooks to pass the same function each
time?

~~~
sophiebits
useCallback is designed for this. useMemo also helps solve the problem from
another angle that previously wasn’t as accessible.

Additional reading: [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).

------
_robbywashere
Call me crazy... but how neat would it be if browsers had native JSX and React
support - and even some optimizations for it/them?

------
Vanit
Hooks seem great for simple usecases but I can't see how you'd not end up with
a mess once you have 3+, and since most components inevitably gain complexity,
why use hooks to start with?

~~~
jrowley
They allow you to abstract certain kinds of logic in really convenient ways.

If you haven’t seen usehooks.com check it out.

Here is a compelling example of combining a few hooks together for an elegant
solution:

[https://usehooks.com/useDarkMode/](https://usehooks.com/useDarkMode/)

~~~
Vanit
I think hooks are just not for me because I don't think those examples look
elegant.

~~~
thatswrong0
I think the `useDarkMode` example is awful. Disregard it. And probably
disregard this as well since I most likely don't capture what makes hooks so
nice from a development perspective:

I'm currently rewriting my product's rich text editor in SlateJS and hooks and
they're making customizing the editor much easier that was possible with class
based components.

SlateJS has a concept of plugins that you can pass to the base editor to
customize behavior. For example, I can write my own "AutoCapitalize" plugin
that will auto-capitalize the first word of each sentence. Or maybe a
"Highlighter" plugin that highlights certain key phrases in the text.

Some of these plugins need to read data from my store and/or call actions, and
some don't. For the ones that do, I can instantiate the plugin with a hook
(e.g. useHighlighterPlugin()), which nicely hides the fact that the plugin is
hooked up to my data store / actions.

Why is this useful?

I have about 10 different text editors in the product, and each has a
different set of plugins associated with each... I need to be able to mix and
match them, reusing some the same plugins over and over.

Maybe one editor has a list of plugins: [autoCapitalizePlugin,
highlightPlugin, spellcheckPlugin]

Another might have: [highlightPlugin, readOnlyPlugin].

Without hooks, to hook up these state and action dependent plugins, I would
have to have higher order components wrapping each of these editors, each of
these HoCs grabbing the different specific data / actions needed to make these
plugins work properly, and passing this data explicitly to construct these
plugins via props. Very difficult to reuse code this way.

I suppose I could write an HoC for each plugin, but then suddenly I'm wrapping
my component in 10 HoCs for 10 plugins. Plus there'd be possibility for props
naming collision.

It would have been impossible to both have reusability _and_ brevity without
hooks.

Instead, I can just create the plugins I want declaratively using hooks:

const highlighterPlugin = useHighlighterPlugin();

const spellcheckPlugin = useSpellcheckPlugin();

------
tekkk
So can someone explain what the author means by the problem of #3:

> _However, there are times when we need to pass an extra parameter. In those
> cases, we cannot use bind because we cannot use bind with arrow functions._

But you can pass the extra argument to the arrow function directly:
`onChange={handleChange('name')}`. And use it as:

    
    
      handleChange = (field) => (e) => {
        this.setState({ [field]: e.target.value });
      }
    

Sure it still has the problems of arrow functions I think the arguments
against it were worded poorly.

------
coldtea
> _This coding pattern also requires more babel transforms. Not a big problem
> but something that developers should be aware of._

This sounds like a totally BS reason in the context where it is said.

