Leave classes behind and grasp this API ↪️ 💪
What are they?
A set of functions that provide a direct API to methods we access on Component instances. We can create stateful components or access the component lifecycle without class instances 🎉
For those in camp TL;DR, scroll down for a collection of demos 👍
Jumping straight in 👟
Consider this app that selects and displays a color value 🎨
We need a class instance to add state.
But with hooks
useState is a hook that allows us to use and update stateful values.
The useState hook provides a stateful value and a way to update it. The argument is the default value. That value can be any type too! 👍
No need for a class instance 🙌
Don’t be afraid of that syntax. useState makes use of Array destructuring.
It’s equal to
Why leave class? 📗
- Minification isn’t great.
- Loss of context where classes try to take on too much.
- Poor separation of concerns in lifecycle methods.
- Requires unstable syntax transforms for class properties.
- HMR issues.
- Subjective use cases, when to use as opposed to stateless function.
If classes work for you, you don’t need to change. Hooks isn’t replacing classes.
There are several hooks. The ones you’ll likely spend most time with are useState and useEffect. Check out the others in the reference.
We use this hook when we want to hook into the the lifecycle stages.
We pass a function to the useEffect hook that runs on every render.
Let’s update our color choosing app from earlier using useEffect.
It’s that simple. Now when the state is updated the body color will change 👍
So that’s running every render? Yep. It doesn’t have to though. There’s an optional second parameter for useEffect. You can pass an Array of values and if those values don’t change between render, the effects won’t execute.
Now we only set the background when color changes 👍
How about other effects such as making API requests or binding user input?
Let’s make a small app that tracks mouse movement.
We use useEffect to bind mouse movement to update some stateful values.
How do we clear up that bind if the component becomes unmounted? We can return a function from our useEffect function for clean up.
Separation of concerns
Hooks allow us to have a better separation of concerns.
Ever seen a class lifecycle method where a lot seems to be going on?
We can avoid this with hooks. As long as our hooks are at the top level we can use as many as we like.
Consider updating our app to also listen for resize events. We don’t need this to happen in our mousemove effect. We can create a separate one. This is a good habit to get into. Especially when we start creating custom hooks.
You can check out a demo in the demos collection 👍
Creating custom hooks
The component in that last example is starting to grow. One of Hook’s greatest attributes is that we can extract their use into custom hooks.
This is a big sell for hooks. You may be familiar with Higher Order Components and render props. We often need a certain structure or style that can prove hard to maintain or justify. This isn’t the case using Hooks.
Consider our example. Tracking mouse movement could be common in our application. Sharing that logic would be ideal. Let’s do it!
Note how our new custom hook returns the current state value. Now any component could use this custom hook to grab the mouse position.
Now we have logic we can share across other components 💪
Let’s consider another example. We have various watches. They look different but they all use the same time ⌚️ We could have a custom hook for grabbing the time. Here’s an example;
- Use when you need to hook into state or a lifecycle stage
- Separate concerns with hooks. No need for “One function does all” approach
- Use in loops, nest them, use them based on conditions.
- Available as of firstname.lastname@example.org
- No breaking changes 🙌
- eslint-plugin-react-hooks@next 👍
A 5 minute intro to React Hooks!
Dive further here ⬇️
You can find all the demos here
As always, any questions or suggestions, please feel free to leave a response or tweet me 🐦!