During the ReactConf 2018 the Hooks were presented and to be honest it have shaken up the React community. If you have not seen “React Today and Tomorrow and 90% Cleaner React With Hooks” video yet, then I encourage you to do so.
Introducing stateless functional components in React 0.14 allowed us to create a smaller reusable blocks of code. But if this component had to handle some more advanced logic, then we had to convert it into a class. Now by introducing React Hooks we are able to inject some logic into functional components and futhermore we can reuse this logic blocks in multiple components.
React Hooks are functions that allow to “power up” your functional components by adding state or allowing them to cause side effects like fetching data from api (and many more!).
Soon they will be able to recreate all functionality of lifecycle methods in functional components, in short — they will replace class components in most cases. Right now, not all methods are available as Hooks:
getSnapshotBeforeUpdate are still missing, but React team says that they are working on it, so we should expect them in near future.
It’s worth to get to know Hooks since:
In the longer term, we expect Hooks to be the primary way people write React components — Hooks FAQ
In React there was no easy way of reusing only component logic, component inheritance is strongly discouraged we could use component composition, practices like render props and higher order components but those are not perfect, they can make code really hard to read and debug due to “wrapper hell”.
Usually components start as small and overtime they getting bigger and bigger, complex ones are hard to follow, understand, debug and test. Hooks let you isolate component logic into smaller functions responsible only for certain pieces (eg. making requests).
The amount of boilerplate needed when you want to use lifecycle methods is also significantly reduced:
And since we are working in one function scope, binding to
this is no longer needed. Hooks are allowing us to reuse our component logic and create solutions for complicated problems in easy way.
But what if I like class components and for some cases they are the best - you may say. Fear not class components still will be there and all your knowledge about React concepts still will be valid, Hooks are just another method to combine them.
Lets take a look on the most basic Hooks provided with React:
This is the most straightforward hook, it allows us to keep information in components state. Unlike
this.state it does not have to be an object and we can use primitive type:
It returns array with two elemets, state and function used to update state. On initial render it returns state is equal to value of first passed parameter.
You can try this one on CodePen.
Second basic hook is
useEffect, since functional components are executed on each render they shouldn’t cause any side effects like mutations, making api calls, subscriptions, this hook does address this shortcoming. By the default, function passed to
useEffect is fired after every render. There is also a way to pass cleanup function, you have to only return it.
It’s worth remembering that previous effect is cleaned up before executing the next effect, so we should think about some way of execution limitation to avoid firing this functions on each update. We can do this by adding some conditions.
If we pass as second parameter array of variables, effect will be fired if one of them change, passing empty array
 will cause firing effect on first mount and before unmounting.
Context API uses render prop to provide context to component and usage looks more like this:
But if we will use Hook, code is much simpler:
I’ve created a simple note taking application, you can check demo here and source code here. I think that the most interesting part of it is usage of
useReducer Hook. This allows to not use redux in smaller apps (and maybe even in middle-sized ones).
Let’s take a look at
useReducer that is used in demo application:
This hook returns array with current state at first position and
dispatch function as second. Now we can change state by dispatching actions eg.
dispatch('NOTE_ADD') will create new note. And all it is done without using any additional library like redux.
Although Hooks looks great and I’m excited to use them in production they come with some tradeoffs. You have to call Hooks at the top level of render function — this means no conditional Hooks because the order in which they are called matter.
Hooks also can only be used in functional components and other hook functions! But they can be mixed, you can put functional component inside class component and vice versa.
Overall I think that introducing Hooks into React is a step in the right direction. It probably take some time to establish some good practices and guidelines but some libraries already introduced Hooks integrations eg. react-i18next.