You're reading from React Key Concepts
Introduction
Throughout this book, one key React feature has been referenced repeatedly in many different variations. That feature is React Hooks.
Hooks power almost all core functionalities and concepts offered by React—from state management in a single component to accessing cross-component state (context) in multiple components. They enable you to access JSX elements via refs and allow you to handle side effects inside of component functions.
Without Hooks, modern React would not work, and building feature-rich applications would be impossible.
Thus far, only built-in Hooks have been introduced and used. However, you can build your own custom Hooks as well. In this chapter, you will learn why you might want to do this and how it works.
Why Would You Build Custom Hooks?
In the previous chapter (Chapter 10, Working with Complex State), when the useReducer()
Hook was introduced, an example was provided in which the Hook was utilized in sending an HTTP request. Here's the relevant, final code again:
const initialHttpState = { data: null, isLoading: false, error: null, }; function httpReducer(state, action) { if (action.type === 'FETCH_START') { return { ...state, // copying the existing state isLoading: state.data ? false : true, error: null, }; } if (action.type === 'FETCH_ERROR') { return { data: null, isLoading: false, error: action...
Custom Hooks: A Flexible Feature
The two independent states of Demo1
and Demo2
show a very important feature of custom Hooks: you use them to share logic, not to share state. If you needed to share state across components, you would do so with React context (see the previous chapter).
When using Hooks, every component uses its own "instance" (or "version") of that Hook. It's always the same logic, but any state or side effects handled by a Hook are handled on a per-component basis.
It's also worth noting that custom Hooks can be stateful but don't have to be. They can manage state via useState()
or useReducer()
, but you could also build custom Hooks that only handle side effects (without any state management).
There's only one thing you implicitly have to do in custom Hooks: you must use some other React Hook (custom or built-in). This is because, if you didn't include any other Hook, there would be no need to build a custom...
A More Complex Example
The previous examples were deliberately rather simple. Now that the basics of custom Hooks are clear, it makes sense to dive into a slightly more advanced and realistic example.
Consider the HTTP request example from the beginning of this chapter:
const initialHttpState = { data: null, isLoading: false, error: null, }; function httpReducer(state, action) { if (action.type === 'FETCH_START') { return { ...state, // copying the existing state isLoading: state.data ? false : true, error: null, }; } if (action.type === 'FETCH_ERROR') { return { data: null, isLoading: false, error: action...
Summary and Key Takeaways
- You can create custom Hooks to outsource and reuse logic that relies on other built-in or custom Hooks.
- Custom Hooks are regular JavaScript functions with names that start with
use
. - Custom Hooks can call any other Hooks.
- Therefore, custom Hooks can, for example, manage state or perform side effects.
- All components can use custom Hooks by simply calling them like any other (built-in) Hooks.
- When multiple components use the same custom Hook, every component receives its own "instance" (i.e., its own state value, etc.).
- Inside of custom Hooks, you can accept any parameter values and return any values of your choice.
What's Next?
Custom Hooks are a key React feature since they help you to write leaner components and reuse (stateful) logic across them. Especially when building more complex React apps (consisting of dozens or even hundreds of components), custom Hooks can lead to tremendously more manageable...
Apply What You Learned
Apply your knowledge about custom Hooks.
Activity 11.1: Build a Custom Keyboard Input Hook
In this activity, your task is to refactor a provided component such that it's leaner and no longer contains any state or side-effect logic. Instead, you should create a custom Hook that contains that logic. This Hook could then potentially be used in other areas of the React application as well.
Note
You can find the starting code for this activity at https://packt.link/rdwd9. When downloading this code, you'll always download the entire repository. Make sure to then navigate to the subfolder with the starting code (activities/practice-1/starting-code
, in this case) to use the right code snapshot.
The provided project also uses many features covered in earlier chapters. Take your time to analyze it and understand the provided code. This is a great practice and allows you to see many key concepts in action.
Once you have downloaded the code and...