Introduction to React Hooks

Joe Ng'ethe
TwigaTech
Published in
5 min readNov 13, 2018

--

A couple of weeks ago, as of the writing of this article, Dan Abramov, took onto the stage to introduce React Hooks to the React community at React Conf 2018 in Henderson, Nevada. And at first glance, I was elated for as much as it introduces new API, it makes it easy for React developers to use the same React features we have been using for years now but in a more easier and elegant way and most importantly, they don’t introduce breaking changes and are 100% backward compatible.

So what exactly are these “Hooks”?

Hooks are a new feature proposal that lets you use state and other React features without writing a class. They’re currently in React v16.7.0-alpha and being discussed in an open RFC.

🎉 That’s right, you can write a function component and have access to its local state and technically also its lifecycle methods 🎉

Motivation of introducing Hooks

Any API introductions should be backed up with a motivation or reason as to “why” and this is no different. Below are some of the reasons why;

  • Currently, it’s hard to use stateful logic between components: If you have been using React for a while, you’d say that HOC and Render Props solves this problem which might be true to some extent but they do introduce some constraints and other pain points. For e.g this patterns require you to restructure your components before you use them and this can be cumbersome and make your code hard to follow. These patterns also introduce the “wrapper hell” where your components are wrapped in a long nested DOM. While this can be filtered out using React Dev tools, it’s not ideal.
  • Complex components can be hard to understand: React components usually start out small but with time they become complex and big which makes them hard to follow and understand. Each lifecycle method can have a bunch of unrelated logic that makes async calls to fetch some data, sets up eventListerners and cleans up these events when the component un-mounts. Based on the complexity of your application, all these can be a bit messy and hard to follow.
  • Classes are confusing to both people and computers: Classes can be confusing to new React devs and in fact it’s one of the hinderance that some people are reluctant to learn React. In order for you to use classes you have to understand how this works and you have to bind your methods in the constructor which can be a bit verbose Classes don’t get minified very well by dev tools and they make hot reloading flaky and unreliable.

We think Hooks are our best shot at solving all of these problems. Hooks let us organize the logic inside a component into reusable isolated units. — Dan Abramov

Show me some code already!

Hooks have been categorized into two categories: Basic and Additional Hooks.

I am going to demo useStateand useEffect but be sure to check the others out for they will come in hand in your development work. I will write about the other hooks in subsequent series' of articles so give me a follow so that you don’t miss out.

Alright lets dive right into it.

useState

Below is a simple controlled form input that tracks the value inputted by the user which will demonstrate useState

useState demo

Explanation

We start by declaring a simple function Component as depicted below;

import React from "react";function App() {return (  <div className="App">    <h1>Hooks demo - useState</h1>    <label htmlFor="name">Name</label>    <input type="text" name="name" value=/>  </div>);}

Next we import useState from react which does the magic for us. We use useState is below;

const [name, setName] = useState("Mary");
  • It returns a pair; the first one is the value and the second is the updater here are using the array destructuring assignment
  • You can pass a default value to it; in this case Mary which will be the default value for name

Next we want to update `name` when a user types in the input field. We do that using the onChange synthetic event which will in turn call the setName method. See code below;

const [name, setName] = useState("Mary");const handleNameChange = e => {  setName(e.target.value);};// full code below import React, { useState } from "react";import ReactDOM from "react-dom";import "./styles.css";function App() {const [name, setName] = useState("Mary");const handleNameChange = e => {setName(e.target.value);};return (<div className="App"><h1>Hooks demo</h1><label htmlFor="name">Name</label><input type="text" name="name" value={name} onChange={handleNameChange} /><pre>{name}</pre></div>);}const rootElement = document.getElementById("root");ReactDOM.render(<App />, rootElement);

useEffect

The Effect Hook lets you perform side effects like making network requests in function components. This is the equivalent of componentDidMount and componentDidUpdate in React class components.

To Demonstrate this we will make a simple component that fetches and renders for Star Wars characters using the Star Wars API

Explanation

First, we import both useState and useEffect along with React

import React, { useEffect, useState } from "react";

Next we destructure characters and setCharaters as we had seen before.

const [characters, setCharacters] = useState([]);

Then we use useEffect to make a fetch to our Star Wars API then we use our setCharacters function to set our state.

useEffect(() => { fetch("https://swapi.co/api/people/")  .then(response => response.json())  .then(({ results }) => {  setCharacters(results); // set characters in state});}, []);

You will notice that we pass a second argument to useEffect which is an empty array . This is an optimization to stop render from being called every time. You can read more about optimization here

One question that experienced React developers might ask at this point is how to we perform cleanups when the component unMounts to stop memory leaks. To do this, we return a function that does the clean up for us which could be unsubscribing to any listeners or canceling any async methods. If we had something that we need to clean up we’d do it like below;

useEffect(() => { fetch("https://swapi.co/api/people/")  .then(response => response.json())  .then(({ results }) => {  setCharacters(results); // set characters in state  return () => someListener.unsubscribe();});}, []);

The full code is as below;

import React, { useEffect, useState } from "react";import ReactDOM from "react-dom";import "./styles.css";function App() {const [characters, setCharacters] = useState([]);useEffect(() => {  fetch("https://swapi.co/api/people/")    .then(response => response.json())    .then(({ results }) => {    setCharacters(results); // set characters in state  });}, []); // empty array because we only run oncereturn (<div className="App">  <h1>Star Wars charaters</h1>  {characters.map((character, index) => (    <div key={index} className="card">    <h5>{character.name}</h5>    </div>  ))}</div>);}const rootElement = document.getElementById("root");ReactDOM.render(<App />, rootElement);

Why should I care?

Hooks allow you to write more cleaner and precise code with less boilerplate code. Below are some reactions from the community.

What Next?

Hooks are awesome there’s no doubt and I’d encourage you to use them in your new components or new projects all together. The two hooks we’ve covered here are not the only ones you can learn about the other hooks here and what’s even better is that you can build you own hooks.

P.S. If you found this article insightful, hold down the clap icon for a few seconds so that this article can reach even more people. Be sure to give me a follow on here or on Twitter so as to get updates of articles like this, cheers!

--

--

Joe Ng'ethe
TwigaTech

Software Engineer: Javascript, React, graphQL, UI’s. Follow me on Twitter @africansinatra