Ahoy Captain Hook(s)!

Jakub Fedoruk
Pragmatists
Published in
3 min readFeb 4, 2020

--

Easy start using useState, useCallback and useEffect React Hooks

In this post, I’d like to show you an easy way to start using React Hooks. All puns to Hook with Robin Williams are intended 😄

I’m keen on using new things and luckily, I work with people who share this approach. Nevertheless, when I first read about React Hooks, I was lost like an old Peter Pan in Neverland. I was looking for Tinkerbell to help me out…

Luckily for me, a perfect occasion showed up sooner than I anticipated. We decided to upgrade our project to the latest React, and one of the High-Order Components (HOC) stopped working. I’ll show you the steps I took to refactor the old and ugly to something new and shiny.

The Pirates way (old component)

The component under review is a HOC responsible for debouncing onChange and onBlur events.

Let’s see the Pirates way of doing things:

withDebouncePirates.js

Argh! Pirates used getDerivedStateFromPropswhich in official React documentation is said to be reserved for rare cases.

Fortunately at Pragmatists, we ❤️ TDD approach — so no surprise — we have tests to check that everything works correctly.

withDebounce.test.js

The Lost Boys way (the new approach)

First of all — React Hooks are cool because you can use a state without using the Class component, so the first step is to refactor the code to use the Function component.

This, coupled with React Hooks, offers us several benefits:

  • we can change the Class component to the Function one
  • we can remove the constructor
  • we don’t need render method — we just return the changed component — exactly what we need our HOC to do.
  • we can remove getDerivedStateFromProps

Let’s go step by step and refactor our code.

  1. Remove the constructor and getDerivedStateFromProps
withDebouncePirates — step 1

2. Change to the Function component

withDebouncePirates — step 2

This requires a little more explanation. We used the Function component which by design does not use State, but we can achieve State functionality using auseState hook.

At first, we changed all code related to this.state to use a useState hook.

The next step was to remove all references to this.

And lastly, we used a useEffect hook to set the value from props. A simple optimization is to set an array of dependency on the value we want to use in our component (props.value in our case). This will update the state only when props.value changes.

3. Use a useCallback hook for debounce

Lodash’s debounce function delays invoking the provided function by a given time. Subsequent calls to the debounced function return the result of the last function invocation. (you can read more in the official documentation)

In our scenario, it’s necessary to wrap Lodash’s debounce in a useCallbackhook, otherwise we would create a new debounced function in every render. This, in the end, would invoke the debounced function several times — and this is not what we need our HOC to do.

withDebounceLostBoys.js

What next?

Since we’re already experts in Hooks, we can take an extra step and change our beloved HOC into a Custom Hook!

This is beyond the scope of this article, but I encourage you to give it a try.

You can read more in the official React documentation.

Final note on useCallback

This hook is intended to save time and resources when you call the same function multiple times. But just as Captain Hook tried to smash all the clocks to stop time, don’t use this hook to boost performance — in the vast majority of cases, it won’t!

Please see the Kent C. Dodds post which explains this in detail.

Summary

I hope you enjoyed the journey of going from an old-style Class component to a new and shiny Functional component with Hooks.

I know it takes a while to absorb this new method, but I can promise that after some time, you’ll feel that this is the only way to go, and will be amazed at how you could ever live without Hooks :)

Please check out my previous post:

You can also discover other posts on our blog!

Github repository: https://github.com/Pragmatists/react-hooks

--

--