rahul

Published on
... views

react custom hooks - demystified in 5 simple steps ⚡️

Authors

Quite often, you'll notice that you're writing a lot of repetitive code to accomplish something 😟 Custom hooks can save the day and end up being asked about in interviews as well! 🚀

Consider the following scenario: You have a webpage with various components and you need to determine whether or not the user is connected to the internet. You might wish to show a popup or take some action if the user loses their internet connection.

When you lose internet connection, Reddit displays this banner.

Alternatively, you might want to disable a form as soon as the user loses internet access to prevent data loss and notify the user.

Step 1

So let's take it one step at a time. First, let's look at how we can tell if a user is connected to the internet or not using DOM APIs.

// Fired off when the user is online
const goOnline = function (event) {
  console.log("I'm online");
};

// Fired off when the user goes offline
const goOffline = function (event) {
  console.log("Oops, I'm offline");
};

window.addEventListener('offline', goOffline);
window.addEventListener('online', goOnline);

Paste that into the browser console and watch what happens if you switch off your internet :)

Step 2

Let's have a look at how we can achieve this in a React component now.

import React, { useEffect } from 'react';

export default function MyComponent() {
  const goOnline = function (event) {
    console.log("I'm online");
  };

  const goOffline = function (event) {
    console.log("Oops, I'm offline");
  };

  useEffect(() => {
    window.addEventListener('offline', goOffline);
    window.addEventListener('online', goOnline);

    /* Be a good citizen. Always cleanup your event 
    listeners when component unmounts */
    return () => {
      window.removeEventListener('offline', goOffline);
      window.removeEventListener('online', goOnline);
    };
  }, []);

  return <div></div>;
}

If you've made it this far, kudos! Let's get going.

Step 3

Now, let's take some action based on the status of the internet connection. When the internet is down, let us display an error message. I am going to use a state variable to keep track of it.

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

export default function MyComponent() {
  const [online, setOnline] = useState(true);

  const goOnline = function (event) {
    console.log("I'm online");
    setOnline(true);
  };

  const goOffline = function (event) {
    console.log("Oops, I'm offline");
    setOnline(false);
  };

  useEffect(() => {
    window.addEventListener('offline', goOffline);
    window.addEventListener('online', goOnline);

    /* Be a good citizen. Always cleanup your event 
    listeners when component unmounts */
    return () => {
      window.removeEventListener('offline', goOffline);
      window.removeEventListener('online', goOnline);
    };
  }, []);

  return <>{!online ? <p>Please check your internet connection!</p> : ''}</>;
}

Codesandbox Link - https://codesandbox.io/s/boring-river-r8pyb9?file=/src/App.js

Turn off your internet connection and see what happens!

Step 4

Yay! We've implemented our logic in a single React component. But what if we want to check the internet status in a different component? One option is to copy and paste the entire code into the other component  But wait, that's a bad idea because you'd end up repeating a lot of code.

Here comes React Custom Hook to save us all!

A point to note: All hooks in React must start with the prefix "use". Let us name our custom hook as useNetwork.

I like to place all my hooks under a separate directory like src/hooks but it's up-to you. Create a new Javascript file called useNetwork.js

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

function useNetwork() {
  //Note that you can make use of other hooks within custom hooks
  const [online, setOnline] = useState(true);

  useEffect(() => {
    const goOnline = function (event) {
      console.log("I'm online");
      setOnline(true);
    };
    const goOffline = function (event) {
      console.log("Oops, I'm offline");
      setOnline(false);
    };
    window.addEventListener('offline', goOffline);
    window.addEventListener('online', goOnline);

    return () => {
      window.removeEventListener('offline', goOffline);
      window.removeEventListener('online', goOnline);
    };
  }, []);

  return online;
}

export default useNetwork;

If you read it line by line, you'll notice that it's very similar to how we wrote the logic in the React component in Step 3, but this time we've isolated it in a separate function called useNetwork. Take note of how we return the state online at the end.

Step 5

We've finally arrived at the last step, and all that remains is to put the custom hook to the test.

import React, { useEffect, useState } from 'react';
import useNetwork from './hooks/useNetwork';

export default function MyComponent() {
  //We import the useNetwork hook and use it like this 🙂
  const online = useNetwork();

  return <>{!online ? <p>Please check your internet connection!</p> : ''}</>;
}

🔥 Andddd voilaa! We've created a custom hook in React 🎉🎉

Codesandbox Link - https://codesandbox.io/s/cold-bush-vopvh8?file=/src/App.js

P.S: If you spot any errors in the article, discussions are welcome below :)

And, if this helped you, drop a reaction to keep me motivated for more such articles 🎉