DEV Community 👩‍💻👨‍💻

Cover image for Making Sense of React Hooks
Dan Abramov
Dan Abramov

Posted on • Originally published at Medium

Making Sense of React Hooks

Originally published on Medium

This week, Sophie Alpert and I presented the “Hooks” proposal at React Conf, followed by a deep dive from Ryan Florence:

I strongly recommend to watch this opening keynote to see the problems we’re trying to solve with the Hooks proposal. However, even an hour is a big time investment, so I decided to share a few thoughts on Hooks below.

Note: Hooks are an experimental proposal to React. You don’t need to learn about them right now. Also, note that this post contains my personal opinions and doesn’t necessarily reflect the positions of the React team.

Why Hooks?

We know that components and top-down data flow help us organize a large UI into small, independent, reusable pieces. However, we often can’t break complex components down any further because the logic is stateful and can’t be extracted to a function or another component. Sometimes that’s what people mean when they say React doesn’t let them “separate concerns.”

These cases are very common and include animations, form handling, connecting to external data sources, and many other things we want to do from our components. When we try to solve these use cases with components alone, we usually end up with:

  • Huge components that are hard to refactor and test.
  • Duplicated logic between different components and lifecycle methods.
  • Complex patterns like render props and higher-order components.

We think Hooks are our best shot at solving all of these problems. Hooks let us organize the logic inside a component into reusable isolated units:

Hooks apply the React philosophy (explicit data flow and composition) inside a component, rather than just between the components. That’s why I feel that Hooks are a natural fit for the React component model.

Unlike patterns like render props or higher-order components, Hooks don’t introduce unnecessary nesting into your component tree. They also don’t suffer from the drawbacks of mixins.

Even if you have a visceral first reaction (as I did at first!), I encourage you to give this proposal a fair try and play with it. I think you’ll like it.

Do Hooks Make React Bloated?

Before we look at Hooks in detail, you might be worried that we’re just adding more concepts to React with Hooks. That’s a fair criticism. I think that while there is definitely going to be a short-term cognitive cost to learning them, the end result will be the opposite.

If the React community embraces the Hooks proposal, it will reduce the number of concepts you need to juggle when writing React applications. Hooks let you always use functions instead of having to constantly switch between functions, classes, higher-order components, and render props.

In terms of the implementation size, the Hooks support increases React only by ~1.5kB (min+gzip). While this isn’t much, it’s also likely that adopting Hooks could reduce your bundle size because code using Hooks tends to minify better than equivalent code using classes. This example below is a bit extreme but it effectively demonstrates why (click to see the whole thread):

The Hooks proposal doesn’t include any breaking changes. Your existing code would keep on working even if you adopted Hooks in the newly written components. In fact, that’s exactly what we recommend — don’t do any big rewrites! It’s a good idea to wait with adopting Hooks in any critical code. Still, we’d appreciate if you could experiment with the 16.7 alpha to provide us with feedback on the Hooks proposal and report any bugs.

What Are Hooks, Exactly?

To understand Hooks, we need to take a step back and think about code reuse.

Today, there are a lot of ways to reuse logic in React apps. We can write simple functions and call them to calculate something. We can also write components (which themselves could be functions or classes). Components are more powerful, but they have to render some UI. This makes them inconvenient for sharing non-visual logic. This is how we end up with complex patterns like render props and higher-order components. Wouldn’t React be simpler if there was just one common way to reuse code instead of so many?

Functions seem to be a perfect mechanism for code reuse. Moving logic between functions takes the least amount of effort. However, functions can’t have local React state inside them. You can’t extract behavior like “watch window size and update the state” or “animate a value over time” from a class component without restructuring your code or introducing an abstraction like Observables. Both approaches hurt the simplicity that we like about React.

Hooks solve exactly that problem. Hooks let you use React features (like state) from a function — by doing a single function call. React provides a few built-in Hooks exposing the “building blocks” of React: state, lifecycle, and context.

Since Hooks are regular JavaScript functions, you can combine built-in Hooks provided by React into your own “custom Hooks”. This lets you turn complex problems into one-liners and share them across your application or with the React community:

Note that custom Hooks are not technically a React feature. The possibility of writing your own Hooks naturally follows from the way Hooks are designed.

Show Me Some Code!

Let’s say we want to subscribe a component to the current window width (for example, to display different content on a narrow viewport).

There are several ways you can write this kind of code today. They involve writing a class, setting up some lifecycle methods, or maybe even extracting a render prop or a higher-order component if you want to reuse it between components. But I think nothing quite beats this:

https://gist.github.com/gaearon/cb5add26336003ed8c0004c4ba820eae

If you read this code, it does exactly what it says. We use the window width in our component, and React re-renders our component if it changes. And that’s the goal of Hooks — to make components truly declarative even if they contain state and side effects.

Let’s look at how we could implement this custom Hook. We’d use the React local state to keep the current window width, and use a side effect to set that state when the window resizes:

https://gist.github.com/gaearon/cb5add26336003ed8c0004c4ba820eae

As you can see above, the built-in React Hooks like useState and useEffect serve as the basic building blocks. We can use them from our components directly, or we can combine them into custom Hooks like useWindowWidth. Using custom Hooks feels as idiomatic as using React’s built-in API.

You can learn more about built-in Hooks from this overview.

Hooks are fully encapsulated — each time you call a Hook, it gets isolated local state within the currently executing component. This doesn’t matter for this particular example (window width is the same for all components!), but it’s what makes Hooks so powerful. They’re not a way to share state — but a way to share stateful logic. We don’t want to break the top-down data flow!

Each Hook may contain some local state and side effects. You can pass data between multiple Hooks just like you normally do between functions. They can take arguments and return values because they are JavaScript functions.

Here’s an example of a React animation library experimenting with Hooks:

Note how in the demo source code, the staggering animation is implemented by passing values through several custom Hooks in the same render function.

https://codesandbox.io/s/ppxnl191zx

(If you want to learn more about this example, check out this tutorial.)

The ability to pass data between Hooks make them a great fit for expressing animations, data subscriptions, form management, and other stateful abstractions. Unlike render props or higher-order components, Hooks don’t create a “false hierarchy” in your render tree. They’re more like a flat list of “memory cells” attached to a component. No extra layers.

So What About Classes?

Custom Hooks are, in our opinion, the most appealing part of the Hooks proposal. But in order for custom Hooks to work, React needs to provide functions with a way to declare state and side effects. And that’s exactly what built-in Hooks like useState and useEffect let us do. You can learn about them in the documentation.

It turns out that these built-in Hooks aren’t only useful for creating custom Hooks. They are also sufficient for defining components in general, as they provide us with all the necessary features like state. This is why we’d like Hooks to become the primary way to define React components in the future.

We have no plans to deprecate classes. At Facebook we have tens of thousands of class components and, like you, we have no intention of rewriting them. But if the React community embraces Hooks, it doesn’t make sense to have two different recommended ways to write components. Hooks can cover all use cases for classes while providing more flexibility in extracting, testing, and reusing code. This is why Hooks represent our vision for the future of React.

But Aren’t Hooks Magic?

You may have been surprised by the Rules of Hooks.

While it’s unusual that Hooks have to be called at the top level, you probably wouldn’t want to define state in a condition even if you could. For example, you can’t define state conditionally in a class either, and over four years of talking to React users I haven’t heard a complaint about this.

This design is crucial to enabling custom Hooks without introducing extra syntactic noise or other pitfalls. We recognize the initial unfamiliarity but we think this tradeoff is worth the features it enables. If you disagree, I encourage you to play with it in practice and see if that changes how you feel.

We’ve been using Hooks in production for a month to see whether engineers get confused by these rules. We found that in practice people get used to them in a matter of hours. Personally, I admit that these rules “felt wrong” to me at first too, but I quickly got over it. This experience mirrored my first impression with React. (Did you like React immediately? I didn’t until my second try.)

Note that there is no “magic” in the implementation of Hooks either. As Jamie points out, it looks pretty similar to this:

https://gist.github.com/gaearon/62866046e396f4de9b4827eae861ff19

We keep a list of Hooks per component, and move to the next item in the list whenever a Hook is used. Thanks to the Rules of Hooks, their order is the same on every render, so we can provide the component with correct state for each call. Don’t forget that React doesn’t need to do anything special to know which component is rendering — React is what’s calling your component.

(This article by Rudi Yardley contains a nice visual explanation!)

Perhaps you’re wondering where React keeps the state for Hooks. The answer is it’s kept in the exact same place where React keeps state for classes. React has an internal update queue which is the source of truth for any state, no matter how you define your components.

Hooks don’t rely on Proxies or getters which can be common in modern JavaScript libraries. So arguably Hooks are less magic than some popular approaches to similar problems. I’d say Hooks are about as much magic as calling array.push and array.pop (for which the call order matters too!)

The design of Hooks isn’t tied to React. In fact, during the first few days after the proposal was published, different people came up with experimental implementations of the same Hooks API for Vue, Web Components, and even plain JavaScript functions.

Finally, if you’re a functional programming purist and feel uneasy about React relying on mutable state as an implementation detail, you might find it satisfactory that handling Hooks could be implemented in a pure way using algebraic effects (if JavaScript supported them). And of course React has always relied on mutable state internally — precisely so that you don’t have to.

Whether you were concerned from a more pragmatic or a dogmatic perspective (if you were at all), I hope that at least one of these justifications makes sense. If you’re curious, Sebastian (the author of the Hooks proposal) also responded to these and other concerns in this comment on the RFC. Most importantly, I think Hooks let us build components with less effort, and create better user experiences. And that’s why I’m personally excited about Hooks.

Spread Love, Not Hype

If Hooks still don’t seem compelling to you, I can totally understand it. I still hope that you’ll give them a try on a small pet project and see if that changes your opinion. Whether you haven’t experienced the problems Hooks solve, or if you have a different solution in mind, please let us know in the RFC!

If I did get you excited, or at least a little bit curious, that’s great! I have just one favor to ask. There are many folks who are learning React right now, and they will get confused if we hurry with writing tutorials and declaring best practices for a feature that has barely been out for a few days. There are some things about Hooks that aren’t quite clear yet even to us on the React team.

If you create any content about Hooks while they’re unstable, please mention prominently that they are an experimental proposal, and include a link to the official documentation . We’ll keep it up to date with any changes to the proposal. We’ve also spent quite a bit of effort to make it comprehensive, so many questions are already answered there.

When you talk to other people who aren’t as excited as you are, please be courteous. If you see a misconception, you can share extra information if the other person is open to it. But any change is scary, and as a community we should try our best to help people instead of alienating them. And if I (or anyone else on the React team) fail to follow this advice, please call us out!

Next Steps

Check out the documentation for Hooks proposal to learn more about it:

Hooks are still in an early stage, but we’re excited to hear feedback from all of you. You can direct it to the RFC, but we’ll also do our best to keep up with the conversations on Twitter.

Please let me know if something isn’t clear, and I’d be happy to chat about your concerns. Thank you for reading!

Top comments (30)

Collapse
 
andy profile image
Andy Zhao (he/him)

If the React community embraces the Hooks proposal, it will reduce the number of concepts you need to juggle when writing React applications.

As a fairly recent React user, I think this is probably the biggest selling point for me. Have a good feeling that Hooks will make things easier to use and understand, as opposed to adding more complexity.

Collapse
 
kayis profile image
K (he/him) • Edited on

This will only ease the pain for new developers that start new projects.

If you start with React and have to work with existing projects, depending on its age, you'll have to wrestle all concepts (Mixins, Higher Oder Components, Render Props).

Collapse
 
ben profile image
Ben Halpern

Yes. But at least with existing codebases, you can sort of pattern match and learn by a bit of trial and error. Too many competing concepts is probably harder when you're green field and the task at hand is still super abstract.

Collapse
 
dan_abramov profile image
Dan Abramov

Yeah. We’re optimizing for long term.

Thread Thread
 
kayis profile image
K (he/him)

Never questioned it :)

Collapse
 
roseanna profile image
Roseanna Mcfarlane

I just wanted to say thanks for all the hard work you do (along with many others such as Sophie) to keep the community updated re React. I follow ya'll on Twitter and don't think I've seen any two people so passionate about keeping people informed and in the loop :)

I just wanted to say that randomly.

Collapse
 
dan_abramov profile image
Dan Abramov

Thank you!

Collapse
 
thomasjunkos profile image
Thomas Junkツ

At the risk of being offtopic, I want to say a big thank you to you, Dan, for your time and effort of posting here :]

Collapse
 
xni profile image
Konstantin • Edited on

Hi, Dan! Thank you for all you and the team are doing for the community!

If you have a couple of spare moments, I had a couple of ideas, maybe you can find then anyhow interesting.

1) You are saying that functions are stateless but in ES6 we have a function* or async function. They can be used as the event generators I suppose. Something like

const eventGenerator = ...;
while (true) {
   await eventGenerator();
   render();
   eventGenerator = ...;
}

Have you considered that option?

2) Just a fun thing: Logo of the city where I was born is an atom - why not to do the next React conf there? ;)

3) This is the example from the React Documentation

useEffect(() => {
    // Update the document title using the browser API
    document.title = `You clicked ${count} times`;
  });

I think it is pretty confusing, there is no reason why this particular example cannot be rewritten as

document.title = `You clicked ${count} times`;
Collapse
 
xni profile image
Konstantin

UPD. Actually found the answer to my third question in the React API Reference.

Collapse
 
sergio profile image
deleteme deleteme

This feels like redux ideas being shoehorned into React. The code itself looks so ugly to me and overly ceremonious. React lost something BIG today and prompted me to look into VueJS as the boring straightforward choice.

Collapse
 
dan_abramov profile image
Dan Abramov

What code examples are you comparing? I don’t see any similarity to Redux in this article but maybe I’m missing something. If anything code using Hooks looks less ceremonious to me than either of the alternatives (like render props or HOCs).

Please elaborate with examples?

Collapse
 
felixbores profile image
Felix Manuel Bores Hevia

I totally disagree my friend. You have to look to Hooks as something that has been 'added', rather than 'changed'. You can keep doing things in React the same way before Hooks came into play, and that, from my point of view, is one of the best accomplishment of the React Team. But dude, Hooks are awesome anyways! :)

Collapse
 
theoutlander profile image
Nick Karnik

That’s an interesting perspective. What parts of it look ugly specifically? This is also optional for now as you can continue working with react without using hooks.

Collapse
 
peter profile image
Peter Kim Frank

Hey Dan, thanks so much for this. It's been very interesting reading and watching the articles on the subject be posted over the past week or so.

As you mentioned:

Note: Hooks are an experimental proposal to React.

Do you think that people actually heed that warning? How do you suggest folks find the right balance between jumping right in to learn and experiment vs. proceeding with sufficient caution?

Collapse
 
anthgrim profile image
Anthony Grimaldi

I've been learning React for over two months, at first it was pretty difficult to me to understand the whole logic behind it, but I got used to it fairly fast. I didn't really like hooks at first, but while doing some exercises here and there with and without them I realize how easy and important hooks become when developing a more interactive app.

Collapse
 
ko15971662 profile image
ko

Hooks although still in development, we are very hopeful, you can also pay attention to FM WhatsAPP GBWhatsAPP FouadWhatsAPP YOWhatsAPP version update and function update use, WhatsApp is a great social app.FouadWhatsAPP

Collapse
 
elisonparker5 profile image
Elison Parker

There has been a lot of pressure, but the actual apps have survived and they are giving best results along with user experience. (bestchainsaws.com.au/best-chainsaw...) This is going to be great.

Thanks for providing such an Amazing information's!

Collapse
 
elisonparker5 profile image
Elison Parker

This is actually the best information that I have seen today! If you want GB WhatsApp other then you can download free on gbwhatsapp.net. They are one of the best fastest WhatsApp apk online. mygbapps.com/ for best Experience.

Collapse
 
lop900 profile image
lop900

Osm! This post is very informative and effective. I got what I was looking for. Here to say thank you. Thanks for sharing FMWhatsapp valuable content.

Collapse
 
meetnawazish profile image
Fashion Clothes

Yes, this is truly working techniques and I really appreciate your efforts on research on react hooks. I would also apply these techniques on gbwhatsapp.net/whatsapp-plus-apk/ for best experience

Collapse
 
alekawa profile image
alekawa

Thank you for this article, very insightful! The topic of React Hooks was also mentioned at the most recent React Conference in Berlin.
You can read a recap of it (also including Hooks) here: selleo.com/blog/react-day-berlin-2...

Collapse
 
rimi887 profile image
rimi887

Great post I have ever seen well explained article thanks for sharing, it's really helpful for me and other as well. Same well to understand post I have also seen on the YouTubeVnaced.org

Collapse
 
marygw profile image
Miya William

Hooks will leave a great turning point for many users.

18 Useful Github Repositories Every Developer Should Bookmark

>> Check out this classic DEV post <<