Hooks were first introduced in React 16.8. They’re great because they let you use more React functionality — like managing the state of your components, or performing post-effects when the state changes in some way, without having to write a class.

In this article, you will learn how to use Hooks in React and how to create your own custom Hooks. Remember, you can use hooks only for functional components.

What is useState Hook?

Your application’s state is bound to change at some point. This could be the value of a variable, an object, or any type of data that exists in your component.

In order for these changes to be reflected in the DOM, we must use a React hook called useState. It looks something like this.

import { useState } from "react";

function App() {
  const [name, setName] = useState("Ihechikara");
  const changeName = () = > {
    setName("Chikara");
  };

  return (
    <div>
      <p>My name is {name}</p>
      <button onClick={changeName}> Click me </button>
    </div>
  );
}

export default App;
Copy the code

Let’s take a closer look at the code above.

import { useState } from "react";
Copy the code

To be able to use this hook, you must import the useState hook from React. We are using a functional component called app.

const [name, setName] = useState("Ihechikara");
Copy the code

After that, you must create your state and give it an initial value (or initial state), which is “Ihechikara”. The state variable is called name, and setName is the function used to update its value.

A good understanding of some of ES6’s features will help you master the basics of React. Above, we used destructuring assignment to assign an initial name value to the state in useState(“Ihechikara”).

return (
    <div>
      <p>My name is {name}</p>
      <button onClick={changeName}> Click me </button>
    </div>
  );
}
Copy the code

Next, the DOM has a paragraph containing the name variable and a button that, when clicked, triggers a function. The changeName() function calls the setName() function and then changes the value of the name variable to the value passed to the setName() function.

Your status values cannot be hard-coded. In the next section, you’ll see how to use the useState hook in your form.

For React beginners, note that you create your functions and variables before returning statements.

How do I use the useState hook in a form

This section will help you understand how to create status values for your form and update them as needed. This process is not very different from what we saw in the previous section.

Import the useState hook as usual.

import { useState } from "react";
Copy the code

We will create the initial state as before. But in this case, it will be an empty string, because we’re dealing with the value of an input element. Hard-coded values mean that the input element will have this value whenever the page is reloaded. That is to say.

  const [name, setName] = useState("");
Copy the code

Now that we have created the state, let’s create the input element in the DOM and assign the name variable to its initial value. It looks something like this.

return (
    <div>
      <form>
        <input
          type="text"
          value={name}
          onChange={(e)= > setName(e.target.value)}
          placeholder="Your Name"
        />
        <p>{name}</p>
      </form>
    </div>
  );
Copy the code

You’ll notice that we didn’t create a function above the return statement to update the value of the status — but that’s fine if you decide to use it that way.

Here, we use the onChange event listener, which waits for any numeric changes in the input field. Whenever there is a change, an anonymous function (taking the event object as an argument) is fired, which in turn calls the setName() function to update the name variable with the current value of the input field.

Here’s what the final code looks like.

import { useState } from "react";

function App() {
  const [name, setName] = useState("");

  return (
    <div>
      <form>
        <input
          type="text"
          value={name}
          onChange={(e)= > setName(e.target.value)}
          placeholder="Your Name"
        />
        <p>{name}</p>
      </form>
    </div>
  );
}

export default App;
Copy the code

What is useEffect Hook?

The effect hook, as its name implies, performs an effect every time there is a state change. By default, it runs after the first render and every status update.

In the following example, we create a state variable, count, with an initial value of 0. Each time you click a button in the DOM, the value of this variable increases by 1. The useEffect hook will run each time the count variable changes and then log some information to the console.

import { useState, useEffect } from "react";

function App() {
  const [count, setCount] = useState(0);

  useEffect(() = > {
    console.log(`You have clicked the button ${count} times`)});return (
    <div>
      <button onClick={()= > setCount(count + 1)}>Click me</button>
    </div>
  );
}

export default App;
Copy the code

If you want to “hook” the React function, it’s always important that you import the first line of code you need to hook. We imported the two hooks used above.

import React, { useState, useEffect } from "react";
Copy the code

Note that you can use the useEffect hook to get data from an external API (as you’ll see in another section of this article), change the DOM in a component, and so on.

UseEffect dependencies

But what if you want your effect to run only after the first render, or if you have multiple states and just want to append a post-effect to one of them?

We can do this by using a dependency array passed in as the second argument in the useEffect hook.

How to run once effect

For the first example, we’ll pass in an array and let the useEffect hook run only once. Here’s an example of how this works.

import { useState, useEffect } from "react";

function App() {
  const [count, setCount] = useState(0);

  useEffect(() = > {
    console.log(`You have clicked the button ${count} times`)}, []);return (
    <div>
      <button onClick={()= > setCount(count + 1)}>Click me</button>
    </div>
  );
}

export default App;
Copy the code

The code above is the same as in the previous section, except that the useEffect hook accepts an empty array [] as its second argument. When we leave the array empty, the effect will run only once, regardless of the change in the state to which it is connected.

How do I append an effect to a particular state

import { useState, useEffect } from "react";

function App() {
  const [count, setCount] = useState(0);

  useEffect(() = > {
    console.log(`You have clicked the first button ${count} times`);
  }, [count]);

  const [count2, setCount2] = useState(0);

  useEffect(() = > {
    console.log(`You have clicked the second button ${count2} times`)
  }, [count2]);

  return (
    <div>
      <button onClick={()= > setCount(count + 1)}>Click me</button>
      <button onClick={()= > setCount2(count2 + 1)}>Click me</button>
    </div>
  );
}

export default App;
Copy the code

In the code above, we created two states and two useEffect hooks. Each state has a post-effect by passing the state names [count] and [count2] to the corresponding useEffect array dependencies.

Therefore, when the state of count changes, the useEffect hook, which is responsible for observing those changes, performs any after-effects assigned to it. This also applies to Count2.

How do you create your own hooks

Now that you’ve seen some of the built-in hooks in React (check the documentation for more), it’s time to create our own custom hooks.

There are many possibilities for what your hook can do. In this section, we’ll create a hook that fetches data from the external API and outputs it to the DOM. This saves you the stress of repeatedly creating the same logic in different components.

Step 1 – Create your file

When creating a new file for a custom hook, make sure the file name begins with “use “. I’ll call my file usefetchdata.js.

Step 2 – Create hook functionality

As mentioned earlier, we’ll use this hook to get data from the external API. It will be dynamic, so nothing needs to be hard-coded. Here’s what we’re going to do.

import { useState, useEffect} from 'react'

function useFetchData(url) {
    const [data, setData] = useState(null);

    useEffect(() = > {
      fetch(url)
        .then((res) = > res.json())
        .then((data) = > setData(data))
        .catch((err) = > console.log(`Error: ${err}`));
    }, [url]);

    return { data };
}

export default useFetchData

Copy the code

To explain what’s going on up there.

  • We import hooks:import { useState, useEffect} from 'react'
  • We create a state to hold the data to be returned — the initial state will be empty:const [data, setData] = useState(null);. The returned data will be usedsetData()Function to updatedataValue of a variable.
  • We create an effect on the first render and each timeurlRun when parameters change.
useEffect(() = > {
      fetch(url)
        .then((res) = > res.json())
        .then((data) = > setData(data))
        .catch((err) = > console.log(`Error: ${err}`));
    }, [url]);
Copy the code
  • We return data variables.return { data };

Step 3 – Create a new file and import custom hooks

So we’ve created our custom hooks. Now let’s create a new component and see how we can use the useFetchData hook in it.

import useFetchData from './useFetchData'
 
function Users() {
    const { data } = useFetchData("https://api.github.com/users");

  return (
      <div>
          {data && (
            data.map((user) =>(
                <div className="text-white" key={user.id}>
                    <h1> {user.login} </h1>
                    <p> { user.type } </p>
                </div>)))}</div>)}export default Users;
Copy the code

Let’s break it down.

  • Let’s name this componentUsers.jsBecause it will be used to get user data from GitHub’s API (which can be any API).
  • We imported a custom hook:import useFetchData from './useFetchData'
  • We refer to the hook and pass in the URL before the return statement.const { data } = useFetchData("https://api.github.com/users");. An API request will be sent to whatever URL you pass in.
  • use&&The DOM is updated only when the data variable is updated with data from the API request, that is, whendata ! = null
  • We loop over the returned data and output it to the DOM.

conclusion

If you’ve followed this up, you should have a good understanding of the React hooks, how to use them, and how to create your own custom hooks. And the best way to fully understand this is to do it, so don’t just read through it.

This article covers the core area of hooks, but it won’t teach you everything you need to know about hooks. So make sure you check the React JS documentation so you can learn more about them.

Thank you for reading. You can follow me on Twitter @ihechikara2.


Ihechikara Vincent Abba

The front-end web developers | | technical writers


If you are reading this, please tweet the authors and show them that you care. thanks

Learn code for free. FreeCodeCamp’s open source courses have helped over 40,000 people land developer jobs. Let’s start