DEV Community

Cover image for Important Custom React Hooks - (Part 1)
Navraj Sandhu
Navraj Sandhu

Posted on • Updated on

Important Custom React Hooks - (Part 1)

It’s been a while since React hooks were released, and everyone has fallen in love with them. I understand because I’m one of you too. Hooks got me hooked!.

Welcome everybody in this two part series of articles. Where we are gonna create a some custom react hooks to increase features as well as productivity of your react app.

Here's the list of hooks we are going to create a in these two parts:

Part 1 :

  • use-window-dimensions(for getting window's width and height)
  • use-outside-click(for detecting outside click from a element)

Part 2:

  • use-window-positions(for detecting window's position)
  • use-scroll-direction(for detecting scroll(up or down))

So before we get started for those who don't know what React and React hooks are? let's have brief introduction for them.

Prerequisites.

  • Basic understanding of Javascript and DOM.
  • Basic understanding of React and React Hooks.

Project Setup

Now let's back to our main agenda.

First we are going new React App with create-react-app. I'd call it custom-react-hooks.

So, open terminal and run the following command.

npx create-react-app custom-react-hooks
Enter fullscreen mode Exit fullscreen mode

Open project in favorite IDE/Text-Editor.In this tutorial I am using VSCode.

After that, go to src folder and create a new folder call hooks.

Till now, our react-app should look like this.

Vs code folder structure

Now, clean src/App.js file like this:


import React from 'react';
import "./App.css";

const App = () => {
    return <div>Hello, let's start coding are custom hooks.</div>;
};

export default App;
Enter fullscreen mode Exit fullscreen mode

You can also delete src/App.test.js, src/setuptest.js, src/logo.svg. I am gonna do so.

Now, that's enough. let's start coding our first custom-react-hooks

1.use-window-dimensions:

In src/hooks folder I'll make a new file called use-window-dimensions.js. This is the file where we'll create our use-window-dimensions hook.

import { useState, useEffect } from "react";



const getDimensions  = () => {
    const { innerWidth : width, innerHeight : height } = window;

    return { width, height }
}

const useWindowDimensions = () => {
    const [windowDimensions,setWindowDimensions] = useState(getDimensions());


    useEffect( () => {

        function handleResize(){
            setWindowDimensions(getDimensions());
        }

        window.addEventListener("resize", handleResize)
        return ( () => { window.removeEventListener("resize", handleResize) } )
    } ,[])

    return windowDimensions
}

export default useWindowDimensions;
Enter fullscreen mode Exit fullscreen mode

Now let's break the code down :

  • getDimensions() function is simply returning window's width and height.
  • useWindowDimensions() function is our hook that will return window dimensions.
  • In useWindowDimensions() functions we've first store window's dimensions in the state.
  • Next we run a useEffect hook to change our state(dimensions) whenever resize event hired on window.
  • And then in our hook we are returning window's height and width.

Testing our hook.

We are going to test our hooks in App.js.

import React from "react";
import "./App.css";
import useWindowDimensions from "./hooks/use-window-dimensions";

const App = () => {
    const { width, height } = useWindowDimensions();

    return (
        <div>
            <h1># First custom hook:</h1>
            <p>
                Window's width is {width} and height is{height}
            </p>
        </div>
    );
};

export default App;
Enter fullscreen mode Exit fullscreen mode

Run dev server on localhost:

npm start
Enter fullscreen mode Exit fullscreen mode

OR

yarn start
Enter fullscreen mode Exit fullscreen mode

Now you outputs should like this:

first-hook-output-1

first-hook-output-2

first-hook-output-3

And that it.
👍 Awesome! we made it.

Now let's move to the next hook.

2. use-outside-click

Like what we've done before create a new file in src/hooks folder called use-outside-click.js


import  { useEffect } from "react";

export default function useOutsideClick(ref,onClick) {
    useEffect(() => {
        if(!ref) return;
        function handleClickOutside(event) {
            if (ref.current && !ref.current.contains(event.target)) {
                onClick(event);
            }
        }

        document.addEventListener("mousedown", handleClickOutside);
        return () => {
            document.removeEventListener("mousedown", handleClickOutside);
        };
    }, [ref,onClick]);
}

Enter fullscreen mode Exit fullscreen mode
  • useOutsideClick is hook which is taking two arguments first ref of element on which we want to detect outside click and second a function that will run when it detect outside click from element.

  • on every mousedown event we check whether the area we clicked on contains targeted element or not. If it contains we are running a function that we'll pass in hook as second argument.

Let's test it.

In src/App.js, let's check whether it's working or not.

import React, { useRef } from "react";
import useOutsideClick from "./hooks/use-outside-click";
import "./App.css";

const App = () => {
    const boxRef = useRef(null);

    useOutsideClick(boxRef, () => {
        console.log("clicked detected outside the box");
    });

    return (
        <div className='app'>
            <div
                ref={boxRef}
                className='box'
                style={{
                    width: "200px",
                    height: "200px",
                    backgroundColor: "lightgreen"
                }}
            >
                Hi, I am the box.
            </div>
        </div>
    );
};

export default App;
Enter fullscreen mode Exit fullscreen mode

And when we clicked outside the green box the it should logged in console as following :

second-hook-output

Amazing 😲, it's working.

Part 2 (coming soon)

Happy coding 😍.

Top comments (1)

Collapse
 
scriptkavi profile image
ScriptKavi

Why create one when you can get all awesome hooks in a single library?

Try scriptkavi/hooks. Copy paste style and easy to integrate with its own CLI