Creating a custom hook in React
Tags: react, javascript, beginners
Published: 2021-03-12 22:44:13

Hello there, thank you for your feedback and comments during this series, We've covered the main hooks provided by React, in my last post we covered useReducer. We'll be looking at how to create a custom hook and some rules to follow. Let's jump right in.

# Why would I need a custom hook?

There are many reasons why you'd want to create your custom hook, but the ultimate purpose of custom hooks is to reuse any hook-related logic all across your app. React is all about reusability as we all know.

Before we continue let's go back to the beginning of this series where we talked about the rules of hooks

### What are the rules of using hooks
* Don't call hooks inside of a loop or conditional statements, or nested functions only call them at top levels

* You can only call hooks in functional components or inside of another hook

React has an  [eslint-plugin](https://www.npmjs.com/package/eslint-plugin-react-hooks) that enforces these rules.

I think it's best to add this last one also, this applies to when creating a custom hook.

* Always prefix your custom hook name with `use` so that React compiler will always check if the rules of hooks were applied.

### Let us create our custom hook!

We will be creating a hook that gets the size of a screen and returns it.

First, we'll create a file named `useWindowSize.js`

```javascript
import { useEffect, useState, useMemo, useCallback } from 'react';
// We can react hooks in our custom hook

const isWindowType = typeof window === 'object';
const useWindowSize = () => {
    const [isClient] = useState(() => isWindowType)

    const getSize = useMemo(
        () => ({
            height: isClient ? window.innerHeight : null,
            width: isClient ? window.innerWidth : null,
        }), [isClient]
    );

    // useMemo because it could cause unnecessary rerender

    const [windowSize, setWindowSize] = useState(getSize);

    const handleResize = useCallback(() => {
        return setWindowSize(getSize);
    },[getSize])

    useEffect(() => {
        if (isClient) {
            window.addEventListener('resize', handleResize);
        }
        return () => window.removeEventListener('resize', handleResize);
    }, []);

    return windowSize;
};

export default useWindowSize;
```

You'd notice that a custom hook is just like a regular javascript function, except you can use react hooks in them.

**Note:** I could as well use this example in my component but I am creating it as a custom component because I would want to use this across multiple components in my project.

### Using a custom hook

We use a custom hook the same way we use other hooks: 

```javascript
import useWindowSize from "./useWindowSize";
// import the hook

export default function App() {
  const { width } = useWindowSize();
  // Use it like you would use a react hook
  return (
    <div className="App">
      {width < 500 ? (
        <div>It's a small screen</div>
      ) : (
        <div>It's not a small screen</div>
      )}
    </div>
  );
}
```
{% codesandbox white-butterfly-idfkb %}

Congratulations! you've just created a custom hook in react. Now that we're done with this article, how can you put what we've learned into action? Go ahead, explore and come up with something. Don't forget that you're allowed to make mistakes and it's perfectly normal to get errors.

Did this article help you in any way? If it did give a like and follow me for more content like this. If you have any questions or comments please post them in the comment section below. Thanks a lot for reading. Keep being amazing and don't forget to be safe out there.