Translate

Friday, 9 October 2020

React Hooks: How to Get Started & Build Your Own

Hooks have been taking the React world by storm. In this tutorial, we’ll take a look at what hooks are and how you use them. I’ll introduce you to some common hooks that ship with React, as well as showing you how to write your own. By the time you’ve finished, you’ll be able to use hooks in your own React projects.

What Are React Hooks?

React Hooks are special functions that allow you to “hook into” React features in function components. For example, the useState Hook allows you to add state, whereas useEffect allows you to perform side effects. Previously, side effects were implemented using lifecycle methods. With Hooks, this is no longer necessary.

This means you no longer need to define a class when constructing a React component. It turns out that the class architecture used in React is the cause of a lot of challenges that React developers face every day. We often find ourselves writing large, complex components that are difficult to break up. Related code is spread over several lifecycle methods, which becomes tricky to read, maintain and test. In addition, we have to deal with the this keyword when accessing state, props and methods. We also have to bind methods to this to ensure they’re accessible within the component. Then we have the excessive prop drilling problem — also known as wrapper hell — when dealing with higher-order components.

In a nutshell, Hooks are a revolutionary feature that will simplify your code, making it easy to read, maintain, test in isolation and re-use in your projects. It will only take you an hour to get familiar with them, but this will make you think differently about the way you write React code.

React Hooks were first announced at a React conference that was held in October 2018, and they were officially made available in React 16.8. The feature is still under development; there are still a number of React class features being migrated into Hooks. The good news is that you can start using them now. You can still use React class components if you want to, but I doubt you’ll want to after reading this introductory guide.

If I’ve piqued your curiosity, let’s dive in and see some practical examples.

Prerequisites

This tutorial is intended for people who have a basic understanding of what React is and how it works. If you’re a React beginner, please check out our getting started with React tutorial before proceeding here.

If you wish to follow along with the examples, you should have a React app already set up. The easiest way to do this is with the Create React App tool. To use this, you’ll have Node and npm installed. If you haven’t, head to the Node.js download page and grab the latest version for your system (npm comes bundled with Node). Alternatively, you can consult our tutorial on installing Node using a version manager.

With Node installed, you can create a new React app like so:

npx create-react-app myapp

This will create a myapp folder. Change into this folder and start the development server like so:

cd myapp
npm start

Your default browser will open and you’ll see your new React app. For the purposes of this tutorial, you can work in the App component, which is located at src/App.js.

You can also find the code for this tutorial on GitHub, as well as a demo of the finished code at the end of this tutorial.

The useState Hook

Now let’s look at some code. The useState Hook is probably the most common Hook that ships with React. As the name suggests, it lets you use state in a function component.

Consider the following React class component:

import React from "react";

export default class ClassDemo extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: "Agata"
    };
    this.handleNameChange = this.handleNameChange.bind(this);
  }

  handleNameChange(e) {
    this.setState({
      name: e.target.value
    });
  }

  render() {
    return (
      <section>
        <form autoComplete="off">
          <section>
            <label htmlFor="name">Name</label>
            <input
              type="text"
              name="name"
              id="name"
              value={this.state.name}
              onChange={this.handleNameChange}
            />
          </section>
        </form>
        <p>Hello {this.state.name}</p>
      </section>
    );
  }
}

If you’re following along with Create React App, just replace the contents of App.js with the above.

This is how it looks:

React Hooks Class Name

Give yourself a minute to understand the code. In the constructor, we’re declaring a name property on our state object, as well as binding a handleNameChange function to the component instance. We then have a form with an input, whose value is set to this.state.name. The value held in this.state.name is also output to the page in the form of a greeting.

When a user types anything into the input field, the handleNameChange function is called, which updates state and consequently the greeting.

Now, we’re going to write a new version of this code using the useState Hook. Its syntax looks like this:

const [state, setState] = useState(initialState);

When you call the useState function, it returns two items:

  • state: the name of your state — such as this.state.name or this.state.location.
  • setState: a function for setting a new value for your state. Similar to this.setState({name: newValue}).

The initialState is the default value you give to your newly declared state during the state declaration phase. Now that you have an idea of what useState is, let’s put it into action:

import React, { useState } from "react";

export default function HookDemo(props) {
  const [name, setName] = useState("Agata");

  function handleNameChange(e) {
    setName(e.target.value);
  }

  return (
    <section>
      <form autoComplete="off">
        <section>
          <label htmlFor="name">Name</label>
          <input
            type="text"
            name="name"
            id="name"
            value={name}
            onChange={handleNameChange}
          />
        </section>
      </form>
      <p>Hello {name}</p>
    </section>
  );
}

Take note of the differences between this function version and the class version. It’s already much more compact and easier to understand than the class version, yet they both do exactly the same thing. Let’s go over the differences:

  • The entire class constructor has been replaced by the useState Hook, which only consists of a single line.
  • Because the useState Hook outputs local variables, you no longer need to use the this keyword to reference your function or state variables. Honestly, this is a major pain for most JavaScript developers, as it’s not always clear when you should use this.
  • The JSX code is now cleaner as you can reference local state values without using this.state.

I hope you’re impressed by now! You may be wondering what to do when you need to declare multiple state values. The answer is quite simple: just call another useState Hook. You can declare as many times as you want, provided you’re not overcomplicating your component.

Note: when using React Hooks, make sure to declare them at the top of your component and never inside a conditional.

Multiple useState Hooks

But what if we want to declare more than one property in state? No problem. Just use multiple calls to useState.

Here’s an example of a component with multiple useState Hooks:

import React, { useState } from "react";

export default function HookDemo(props) {
  const [name, setName] = useState("Agata");
  const [location, setLocation] = useState("Nairobi");

  function handleNameChange(e) {
    setName(e.target.value);
  }

  function handleLocationChange(e) {
    setLocation(e.target.value);
  }

  return (
    <section>
      <form autoComplete="off">
        <section>
          <label htmlFor="name">Name</label>
          <input
            type="text"
            name="name"
            id="name"
            value={name}
            onChange={handleNameChange}
          />
        </section>
        <section>
          <label htmlFor="location">Location</label>
          <input
            type="text"
            name="location"
            id="location"
            value={location}
            onChange={handleLocationChange}
          />
        </section>
      </form>
      <p>
        Hello {name} from {location}
      </p>
    </section>
  );
}

Quite simple, isn’t it? Doing the same thing in the class version would require you to use the this keyword even more.

Now, let’s move on to the next basic React Hook.

Continue reading React Hooks: How to Get Started & Build Your Own on SitePoint.



No comments:

Post a Comment