Learn Hooks in Just 5 Steps — With Examples

Learn Hooks in Just 5 Steps with Example

You don’t really know you need them until you use them

In this article, we are going to learn to use hooks in react applications, by building an MVC that you might have built while learning any other framework, the Todo MVC.

I will be sharing a Codesandbox link after every step with the full code till that point so that you can play with it yourself and see how things work in real-time.

I am assuming that you know the basics of ReactJS and ES6 syntax, if not then I have listed down some resources in the Requirements section to get you covered up.

TLDR;

If you want to jump straight to the code then here is the GitHub repository with the final code and the sandbox, if you want to play around with it in Codesandbox.

todo-with-hooks-final – CodeSandbox

Requirements

  • Basic Array methods in javascript
  • ES6 concepts like arrow functions, spread syntax, etc.
  • Basic ReactJS and state and lifecycle.

That’s all you need to know to learn hooks, if you are skeptical about your ReactJS skills then you can go through this awesome tutorial, by the official React documentation.

Preface

A hook is a function provided by React that lets you hook into React features from your function components.

Before React 16.8.0, the functional components were called presentational or dumb components because, they were only usually used to represent some UI that could be manipulated using props, but they cannot maintain their own state, so we need to create classes for creating meaningful applications.

But now things have changed with the introduction of hooks, now functional components can have their own state. Now with hooks, you can build full-fledged react applications without creating a single class.

1. The Initial Setup

Initially, I have just created a simple React application using, create-react-app that has a simple function component and the UI with styles.

I have integrated all the styles beforehand so that we can focus only on the functionality part.

Here is the sandbox with the initial setup –

todo-with-hooks-initial-ui – CodeSandbox

2. Loading the data

As you can see the data in this app is currently static, so the first thing we need to do is, create a structure for the todos and load them in their corresponding sections.

So we will be creating an array of objects representing the tasks where each object represents a task. For now, since we only need the name of the task and its status (whether it is completed or not), our task object will have two keys –

{
name: 'Do pushups', // Name of the task
    status: true        // Completion status where true represents   }                       //  complete and false represents pending

Now if it were a Class component we would have created a state variable and assigned this array to it like

https://medium.com/media/2e4642332a1d1d5349a84abbbd99391d/href

But since we don’t have any class components here, we will use the useState hook to create a variable called todos and initialize it with an array something just like this-

https://medium.com/media/5bfa3f1e2c455a08d9243886d93f124c/href

The useState hook takes the initial value of the variable as input and returns an array of two elements with the first one representing the value of the variable and the second one, a method to update the value. If the above implementation confuses you then you can write it like this –

https://medium.com/media/c27270a2d84b40713734f2f4ab286207/href

Now since we have the array of tasks available we will just filter them according to their statuses and map them to their respective sections –

https://medium.com/media/5b1f5912104e41106d1393e9e370a8cb/href

Here is the sandbox with the full code till this point –

todo-with-hooks-loaded-data – CodeSandbox

3. Adding tasks

Since we have our todos array ready, we can now start adding tasks.

I had already created an input field, but we will also be needing a state field to maintain its value.

So we will create another useState hook for maintaining the value of the input field and initialize it with an empty string –

const [value, setValue] = useState("");

Now I hope you are able to see how hooks are different from state in class components. If it were a class component our state would have been something like this –

this.state = {
todos: [....],
value: ""
};

And it would have provided us with just a single this.setState() function to update the values of both the variables. But with hooks, we now have separate functions for updating the values of both the variables.

Let’s integrate this into our app –

https://medium.com/media/946841634bb47ab6ed1542cf2532ea31/href

Okay so the input field works now but we still don’t have anything to create tasks, so let’s create a function to add tasks using the setTodos method, we created in the previous step.

https://medium.com/media/9b2636483ca24af3055c7305a9d0a779/href

This method uses array destructuring to append a new task with the value of the input field. After creating a task, we also need to clear the value from the field since the task is now added so we usesetValue(“”) to clear the input field.

We then add this function to the onClick handler of the Add button.

So now we can add tasks to our todo list.

One last remaining touchup I would like to add is to add a task when the user presses enter after entering the task in the input field.

So for that, we will use the onKeyDown event handler of the input to detect the ‘enter’ key press.

https://medium.com/media/d28487497567ab2f716ead44f4353400/href

Here is the sandbox with the full code till this point –

todo-with-hooks-add-task – CodeSandbox

4. Updating and deleting the tasks

In this step, we will make the status checkbox and the delete button functional so that we can mark the tasks as completed or pending.

Now since we are having different sections for completed and pending tasks keeping track of the task on which the action is being performed with just the index would be difficult and incorrect if want to extend our app.

So we will now add an id attribute to the task object, which will help in uniquely identifying individual tasks and, for the sake of this tutorial we would just assign, the id as a combination of Date.now() and Math.random() to make sure that they are unique. Our addTodo function looks something like this now –

https://medium.com/media/522c0362fd05e1b8818d84a92d63f689/href

Now for updating the status of a task, we would just pass the id of the task that is being updated and toggle the status of that task accordingly in the array. So we would create a function and call it on the onChange event of the checkbox.

https://medium.com/media/054d0457a6c02151341ff036340a3848/href

Similarly, for delete, we would just filter out the task with the given id from the array.

https://medium.com/media/f9718e898bfc52bb17dff38727449f1f/href

Now our todo app is almost complete with everything functional, except that everything is lost once we hit refresh, or reopen the tab.

Here is the sandbox with the full code till this point –

todo-with-hooks-update-delete – CodeSandbox

5. Maintaining the data

In this step, we will learn how to store the tasks so that they are not lost if the user closes the tab or refreshes the page.

You can use anything to store the data, like, firebase, MongoDB or any other database.

For the simplicity of our app, I will be using the browser’s localStorage, using a library called localForage that uses localStorge’s API.

So if it were a class component then we would have created a function that saves the data every time the todos array is updated and we would have called that function as a callback of setState() in the addTodo(), deleteTodo() and handleCheckboxChange() methods, something just like this –

https://medium.com/media/81258c9c164014af0e2b06246d410790/href

But guess what, hooks don’t have callbacks.

They have something much better that replaces the lifecycle methods such as componentDidMount(), componentDidUpdate() and setState callbacks.

Say hello to the useEffect hook.

import React, { useState, useEffect } from "react";
...
useEffect (() => {
// Anything you want to do when the component rerenders
})

useEffect is called every time our component re-renders i.e. the state or the props changes.

But if we save the data every time the state gets updated then that would we be very inefficient since the value state also gets updated when we type something in the input field.

To solve this problem useEffect hook takes another parameter as an array which consists of the state variables that need to be monitored for an update. So with this feature, we only have to write this –

https://medium.com/media/9f764b948b21f04430963e6932ad185f/href

in our component to save the todos every time the array gets updated.

Simple isn’t it.

Now every time you update your tasks you can head over to the application tab in the inspect window and see the data getting saved.

One last thing remaining is to fetch this array when the page is refreshed or the tab is closed and opened again.

Once again, if it were a class component we would have used componentDidMount() here but since we are using the useEffect hook, it has a feature by which if we pass an empty array as the second parameter it behaves like componentDidMount().

So we will create another useEffect hook that takes an empty array as the second parameter and then fetches the todos array from the localStorage and update the value of todos state variable using setTodos.

https://medium.com/media/358c5b12bf01703095a1165a38908035/href

And finally, now we have our fully functional Todo app ready.

Here is the sandbox with the full code till this point, I have also refactored the code a bit by creating a separate component for the tasks –

todo-with-hooks-final – CodeSandbox

Further Reading

  • I highly recommend you to go through the React docs for hooks.
  • Also, this video in which Dan Abramov releases hooks during React Conference.
  • Test your understanding of the concept by adding features like editing a task or repositioning a task, and open a pull request in the GitHub repo. I’ll merge the PR if I find it accurate and will mention the changes if there are any in the PR itself.

Please 👏 if you like this article, it really motivates people like me to keep writing such articles. You can reach me out or know more details about me on Github, Twitter, Linkedin, or my website.

Thanks for reading 🙂

https://medium.com/media/3c851dac986ab6dbb2d1aaa91205a8eb/href


Learn Hooks in Just 5 Steps — With Examples was originally published in Hacker Noon on Medium, where people are continuing the conversation by highlighting and responding to this story.