The Real Power of React Custom Hooks

A Hook

Before React Hooks, non class-based components were often called stateless functional components, or dumb components. Such components wouldn’t have access to state nor do they have any lifecycle hook. As a result, the stateless functional component relies on its props as the only input.

For the mere purpose of presentation, the stateless functional component is almost always preferred over a class-based component due to its simpler syntaxes.

However, modern application is not all about presentation. Often, we need our application to remember stuff or perform a specific task when it reaches a certain lifecycle. Stateless functional components can do neither, the answer has to be a class component.

As a smarter counterpart, the class component has a built-in state object that you can access via this.state. It also provides a number of callbacks to several points of its lifecycles such as componentDidMount, componentWillUnmount, componentWillReceiveProps, and many more. Consequently, for anything beyond presentational, there is no alternative to class component.

The problem is, class components are hard to use. People can understand how states, props, and data flows work perfectly but still struggle to understand class. Due to these reasons, React team felt that there has to be a better solution — and the rest is history.

What Are React Hooks Anyway?

There are two types of Hooks in React.

State Hooks

React State Hooks

A State Hook provides a getter and setter that associates to a single value in a component. The state provided by a State Hook can be of any type, be it object, array, string, number, null, or whatever you want.

Just like state in a class component, changes in a state value causes the component to perform a re-render. For a smaller component with simpler states, useState is the perfect solution.

useState Example

However, useState falls short when it comes to complex state logic that involves multiple values and sub-values. As an alternative, you can use useReducer to solve that.

Effect Hooks

React Effect Hooks

Side-effect (or just “effect”) refers to a programming paradigm in which a function affects something outside its local scope. A function with side-effect makes it non-deterministic-that is the result of a function may differ every time it is called.

An Effect Hook lets you perform said side-effect. Side-effects could take many forms: data-fetching, subscription, or manually changing DOM in React component.

For example, with useEffect you can tell React to invokes an effect after the initial render. useEffect basically tells React to do something after a render. This Hook although not the same, can be thought of as the alternative to class component lifecycle callbacks such as componentDidMount, componentWillReceiveProps, etc.

One of the common use cases for this Hook is to fetch data after the initial render.

useEffect Example

The example above is considered a component with side-effect because it depends on external data-source. there’s no guarantee that the component always renders the same output.

Why Is Custom Hook Necessary?

A component of this kind would require a state to store the value, an effect to retrieve from local storage, and a handler to set updated value.

No Custom Hook

The solution is straightforward. You happily implement the details. But you realize the same functionality is needed elsewhere. So you do what you’ve always done, copy and paste the solution, perhaps with slight modification, and call it a day.

Now, what if the same functionality is needed in three more places?

To solve this, React allows you to write custom Hooks that extract specific business logic into a reusable piece.

Let’s see how it works.

useLocalStorage Custom Hook

Use the custom Hook.

With Custom Hook

Now that we move the cumbersome business logic to a custom Hook, any component that relies on the same functionality can benefit from it without us having to rewrite it.

What Makes Custom Hooks Powerful?

Custom Hook Is Just Another Function

Custom Hook Is Stateful

Furthermore, each custom Hook gets its own isolated state. When two components access the same custom Hook, they don’t share the state. Instead, they will both get a completely independent state.

To showcase the statefulness and isolated characteristic of a custom Hook, let’s revisit the previous useLocalStorage Hook example.

Suppose we want to pull data from multiple local storage fields.

Multiple Custom Hooks

We would simply call another useLocalStorage with slight modification. Both custom Hooks never share the state because they are completely isolated.

Conclusion

Fortunately, with the addition of React Hooks, the wrapper hell can now be easily avoided. There are, however, some rules we need to keep in mind when making use of React Hooks API.

  • Only call Hooks either from React function component or custom Hooks.
  • Only call Hooks at the top level of your component.

Finally, React Hooks are flexible and highly customizable to suit your needs. You can write custom Hooks that abstract away the complexity and reuse them between components.

Bonus

useMedia → Tracks the state of CSS media query.

React Router Hooks → If you use React Router, Access the state of the router and perform navigation from inside the components.

useClippy → Performs a “copy to clipboard”.

useDocumentTitle → Change the title of your document.

useDebounceCallback & useThrottleFn → Controls the rate at which the function is called.

useTranslation → Translate your document

useDarkMode → Enables and disables the dark mode

useQueryParam → Encode and decode data of any type as a query parameter

useLocalStorage → Persistent state for your React component

Originally published at https://frendyguo.me.

Frontend Engineer | Reader | Gamer — https://frendyguo.me

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store