logo le blog invivoo blanc

Introduction to React Hooks

27 March 2020 | Front-End | 0 comments

Hooks were introduced in February 2019 as part of React 16.8. They will help you make your code clearer and better structured. The classic class based syntax and idiomw are still still supported, and will keep being supported for the foreseeable future. So no rush to rewrite your current components.

After reading this article, I expect you’ll be able to understand what is happening behind code written using hooks. I will also give you a few pointers to start writing your own hook-based code.

Why changing?

React is a state management library, so it should be easy to write stateful web pages. It may be weird, but, did you notice how easy it is to create stateless components in React when compared to stateful components?

A stateless (functional) component is basically a JavaScript function. It is simple like that. A stateful component? Be ready to understand the lifecycle of a component, and spread the business logic you need to implement into a couple of lifecycle functions.

In the following example, we create a simple function to display the value of a counter:

function Counter({value}) {
  return (
    <div>
      The value of the counter is {value}
    </div>
  );
}

Things get more complex when your component needs to have a internal state. The traditional way of handling that was to transform your component into a class component. Then, similarly to other programming languages, using different methods of your class as different states in a more complex lifecycle.

One of the problems this brings, is that JavaScript is not a typical object oriented language (more information on my previous articles, like this one and this one). So, in practics, you need to deal with the multiple pitfalls of the class based syntax in JavaScript.

Introduction to Hooks

Another problem is that, in terms of code organisation, lifecycle methods are not ideal, as they force you to mix different concerns on a couple of different lifecycle methods; making code harder to read and maintain.

How? The main catch of hooks is that they really look like React functional components. Aside from the fact that they are stateful. The good methodology to write a maintenable react component seems to be always starting with a completely functional component, then adding hooks.

When? When you need to deal with some form of state-change on your component.

From the point of view of your component, a hook is just a function called from inside your component’s function. The magic is not on what the function does, but on what it returns. The idea is that you’ll use the result of the function to buil the state of your componen. React will re-render your component when re-render your component when the state if the hooks it calls change.

Let’s start with a non extensive list of standard hooks:

  • useState: add state to a function component (just like setState in the class components)
  • useEffect: manage sideffects (document changes, HTTP, etc)
  • useContext: manage context changes
  • useReducer: manage redux state changes

Example using Hooks

In the following example, we we’ll add a internal state to our Counter component. All hooks look like a function call inside our component method. This function is the fronteer between the rendering code that depends on some state, and the external world that depends on it.

The role of the code that is inside your component function does not change: it should render the component, based either on its props, or on the values returned by hooks. As a developer, you need to trust react so that it will call your component function everytime a new render is necessary.

function CounterHook() {
  const [value, setValue] = useState(0);

  return (
    <div onClick={() => {setValue(value + 1)}}>
      The value of the counter is {value}
    </div>
  );
}

In the following code snippet, we can see how to write the same component using the standard class-base syntax. Notice the incidental added complexity. We need to add a `constructor` with a predefined form, we need to handle the fact that state changes are asynchronous and we need to separate the initialization code from the rendering code.

class CounterClass extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: 0};
  }
  render() {
    return (
      <div onClick={() => this.setState((state) =>{ return {value: state.value + 1}; } )}>
        The value of the counter is {this.state.value}
      </div>
    );
  }
}

Futher reading

In this article, I hope I gave you a headstart on this new feature introduced one year ago on the React world. I hope you can see how much easier to understand is hooks based code.

But this is only the beginning. If you want to go further, there goes a list of links to web resources that will help you.