15 More Useful React Custom Hooks For Everyone - part 2
Tags: webdev, javascript, react, beginners
Published: 2023-01-24 21:43:12

First, thank you so many guys for supporting the first part. In this article, I've come up with 15 more react custom hooks that can be helpful for you whether you are building a small or large project. 

**NOTE**: I've used some of the custom hooks here, which I explained in the first part. If you haven't read the first part, you might have problems understanding the code. That's why I recommend reading the first part first. You can find the article here: [first part](https://dev.to/arafat4693/15-useful-react-custom-hooks-that-you-can-use-in-any-project-2ll8)

> Table of contents

- [useMediaQuery](#1-usemediaquery)
- [useGeolocation](#2-usegeolocation)
- [useStateWithValidation](#3-usestatewithvalidation)
- [useSize](#4-usesize)
- [useEffectOnce](#5-useeffectonce)
- [useClickOutside](#6-useclickoutside)
- [useDarkMode](#7-usedarkmode)
- [useCopyToClipboard](#8-usecopytoclipboard)
- [useCookie](#9-usecookie)
- [useTranslation](#10-usetranslation)
- [useOnlineStatus](#11-useonlinestatus)
- [useRenderCount](#12-userendercount)
- [useDebugInformation](#13-usedebuginformation)
- [useHover](#14-usehover)
- [useLongPress](#15-uselongpress)

---

## 1. useMediaQuery

```jsx
import { useState, useEffect } from "react"
import useEventListener from "../13-useEventListener/useEventListener"

export default function useMediaQuery(mediaQuery) {
  const [isMatch, setIsMatch] = useState(false)
  const [mediaQueryList, setMediaQueryList] = useState(null)

  useEffect(() => {
    const list = window.matchMedia(mediaQuery)
    setMediaQueryList(list)
    setIsMatch(list.matches)
  }, [mediaQuery])

  useEventListener("change", e => setIsMatch(e.matches), mediaQueryList)

  return isMatch
}
```
`useMediaQuery` is a custom React hook that allows a component to check if a specific media query matches the current viewport and keep track of the match status. In addition, it uses the built-in `useState` and `useEffect` hooks from the React library and a custom hook called `useEventListener`(this hook is exaplined in the first part) that allows a component to add an event listener to a specific **DOM** element and execute a callback function when the event occurs.

The hook takes one argument:

- **mediaQuery** is a string representing the media query to check for.

The `useEffect` hook creates a MediaQueryList object from the media query and sets the initial match status.
The `useEventListener` hook adds a **change** event listener to the **MediaQueryList** object and updates the match status when the event occurs.
It returns a boolean value `isMatch` that indicates whether the media query matches the current viewport.

Here is an example of how you can use this hook:

```jsx
import useMediaQuery from "./useMediaQuery"

export default function MediaQueryComponent() {
  const isLarge = useMediaQuery("(min-width: 200px)")

  return <div>Large: {isLarge.toString()}</div>
}
```
This hook can be helpful in situations where you want to change the layout or behavior of a component based on the current viewport, such as adapting the layout to different screen sizes or device types.

## 2. useGeolocation

```jsx
import { useState, useEffect } from "react"

export default function useGeolocation(options) {
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState()
  const [data, setData] = useState({})

  useEffect(() => {
    const successHandler = e => {
      setLoading(false)
      setError(null)
      setData(e.coords)
    }
    const errorHandler = e => {
      setError(e)
      setLoading(false)
    }
    navigator.geolocation.getCurrentPosition(
      successHandler,
      errorHandler,
      options
    )
    const id = navigator.geolocation.watchPosition(
      successHandler,
      errorHandler,
      options
    )
    return () => navigator.geolocation.clearWatch(id)
  }, [options])

  return { loading, error, data }
}
```
`useGeolocation` is a custom React Hook that allows a component to access the browser's geolocation API and keep track of the device's current position. It uses the React library's built-in **useState** and **useEffect** hooks.

The hook takes one optional argument: **options** is an object that allows you to configure the **geolocation** API, such as the maximum age of the cached position and the timeout before the error callback is called.

The **useEffect** hook calls the geolocation **API** and the `getCurrentPosition` and `watchPosition` methods. The callback passed to these methods updates the state with the current position data and set the loading and error state accordingly.

It returns an object containing three properties:

- **loading** is a boolean indicating if the geolocation data is currently being fetched.

- **error** is an error object if there is an error fetching the geolocation data.

- **data** is an object containing the latitude, longitude, accuracy, altitude, and other properties of the device's current position.

Here is an exmaple of how you can use this hook:

```jsx
import useGeolocation from "./useGeolocation"

export default function GeolocationComponent() {
  const {
    loading,
    error,
    data: { latitude, longitude },
  } = useGeolocation()

  return (
    <>
      <div>Loading: {loading.toString()}</div>
      <div>Error: {error?.message}</div>
      <div>
        {latitude} x {longitude}
      </div>
    </>
  )
}
```
This hook can be helpful in situations where you want to access the user's location data, such as displaying nearby locations on a map or providing location-based services.

## 3. useStateWithValidation

```jsx
import { useState, useCallback } from "react"

export default function useStateWithValidation(validationFunc, initialValue) {
  const [state, setState] = useState(initialValue)
  const [isValid, setIsValid] = useState(() => validationFunc(state))

  const onChange = useCallback(
    nextState => {
      const value =
        typeof nextState === "function" ? nextState(state) : nextState
      setState(value)
      setIsValid(validationFunc(value))
    },
    [validationFunc]
  )

  return [state, onChange, isValid]
}
```
`useStateWithValidation` is a custom React Hook that allows a component to keep track of a state value and validate the state value on each change. It uses the React library's built-in `useState` and `useCallback` hooks.

The hook takes two arguments:

- **validationFunc** is a function that will be called with the new state value on each state change. It should return a boolean indicating whether the state value is valid.

- **initialValue** is the initial value of the state.

The `useState` hook is used to initialize the state with the provided initial value and the validation state with the result of the validation function called on the initial value.

The `useCallback` hook is used to create a callback function that updates the state and validation state with the new value passed to it.

It returns an array containing three properties:
- **state** is the current state value.

- **onChange** is a callback function that should be passed to an input/form element and will update the state and validation state with the new value.

- **isValid** is a boolean indicating whether the state value is valid.

Here is an example of how you can use this hook:

```jsx
import useStateWithValidation from "./useStateWithValidation"

export default function StateWithValidationComponent() {
  const [username, setUsername, isValid] = useStateWithValidation(
    name => name.length > 5,
    ""
  )

  return (
    <>
      <div>Valid: {isValid.toString()}</div>
      <input
        type="text"
        value={username}
        onChange={e => setUsername(e.target.value)}
      />
    </>
  )
}
```
This hook can be helpful in situations where you want to validate the input values of a form or validate any other state value before performing a specific action.

## 4. useSize

```jsx
import { useState } from "react"
import { useEffect } from "react/cjs/react.development"

export default function useSize(ref) {
  const [size, setSize] = useState({})

  useEffect(() => {
    if (ref.current == null) return
    const observer = new ResizeObserver(([entry]) => setSize(entry.contentRect))
    observer.observe(ref.current)
    return () => observer.disconnect()
  }, [])

  return size
}
```
`useSize` is a custom React Hook that allows a component to track the size of an element, passed as a reference. It uses the React library's built-in `useState` and `useEffect` hooks.

The hook takes one argument, `ref`, which refers to the element you want to track its size.

The `useState` hook initializes an empty object as the size state.
The `useEffect` hook is used to observe the element's size passed by reference. First, it creates a new instance of **ResizeObserver**, a built-in browser **API** that allows tracking the size of an element. Then, it invokes the callback function passed to it, which updates the size state with the `contentRect` property of the entry passed to it.

It returns an object containing the element's size with properties: `width`, `height`, `x`, `y`, etc.

Here is an example of how you can use this hook:

```jsx
import { useRef } from "react"
import useSize from "./useSize"

export default function SizeComponent() {
  const ref = useRef()
  const size = useSize(ref)

  return (
    <>
      <div>{JSON.stringify(size)}</div>
      <textarea ref={ref}></textarea>
    </>
  )
}
```
This hook can be helpful in situations where you want to track the size of an element and change the component behavior or layout based on its size.

## 5. useEffectOnce

```jsx
import { useEffect } from "react"

export default function useEffectOnce(cb) {
  useEffect(cb, [])
}
```
`useEffectOnce` is a custom React Hook that allows a component to run an effect only once. It is a simpler version of the built-in `useEffect` hook, enabling you to specify how often an effect should run.

The hook takes one argument, `cb`, which is the callback function that contains the logic of the effect.
It calls the built-in `useEffect` hook and passes the cb function as the first argument and an empty array as the second argument.
An empty dependency array is passed to the `useEffect` hook, which means that the effect will only run once on the initial render.

Here is an example of how you can use this hook:

```jsx
import { useState } from "react"
import useEffectOnce from "./useEffectOnce"

export default function EffectOnceComponent() {
  const [count, setCount] = useState(0)

  useEffectOnce(() => alert("Hi"))

  return (
    <>
      <div>{count}</div>
      <button onClick={() => setCount(c => c + 1)}>Increment</button>
    </>
  )
}
```
This hook can be helpful when you want to run an effect, such as initializing a library, only once in a component, instead of running it on every render.

## 6. useClickOutside

```jsx
import useEventListener from "../13-useEventListener/useEventListener"

export default function useClickOutside(ref, cb) {
  useEventListener(
    "click",
    e => {
      if (ref.current == null || ref.current.contains(e.target)) return
      cb(e)
    },
    document
  )
}
```
`useClickOutside` is a custom hook that listens for a **click** event on the document, and when a click happens, it checks if the event target is within the current ref. If it is not, it will call the callback function passed in. This hook uses `useEventListener`(this hook is exaplined in the first part) that allows a component to add an event listener to a specific **DOM** element and execute a callback function when the event occurs.

Here is an exmaple of how you can use this hook:

```jsx
import { useRef, useState } from "react"
import useClickOutside from "./useClickOutside"

export default function ClickOutsideComponent() {
  const [open, setOpen] = useState(false)
  const modalRef = useRef()

  useClickOutside(modalRef, () => {
    if (open) setOpen(false)
  })

  return (
    <>
      <button onClick={() => setOpen(true)}>Open</button>
      <div
        ref={modalRef}
        style={{
          display: open ? "block" : "none",
          backgroundColor: "blue",
          color: "white",
          width: "100px",
          height: "100px",
          position: "absolute",
          top: "calc(50% - 50px)",
          left: "calc(50% - 50px)",
        }}
      >
        <span>Modal</span>
      </div>
    </>
  )
}
```
This hook can be helpful when you need to detect clicks outside of a specific element, such as when creating a modal component, and you want to close the modal when the user clicks outside of it.

## 7. useDarkMode

```jsx
import { useEffect } from "react"
import useMediaQuery from "../16-useMediaQuery/useMediaQuery"
import { useLocalStorage } from "../8-useStorage/useStorage"

export default function useDarkMode() {
  const [darkMode, setDarkMode] = useLocalStorage("useDarkMode")
  const prefersDarkMode = useMediaQuery("(prefers-color-scheme: dark)")
  const enabled = darkMode ?? prefersDarkMode

  useEffect(() => {
    document.body.classList.toggle("dark-mode", enabled)
  }, [enabled])

  return [enabled, setDarkMode]
}
```
This hook allows for a **dark mode** feature in a React application. It uses the custom **useLocalStorage**(explained in the first part) hook to get and set the **dark mode** preference in local storage and the `useMediaQuery` hook to check if the user's device or browser prefers dark mode. 

The hook uses useEffect to toggle the **dark-mode** class on the document body based on the value of the enabled variable, which is determined by the user's preference in local storage or the device's preference for dark mode. This allows the application's styles to be adjusted when the dark mode is enabled. Finally, the hook returns a tuple containing the current state of the dark way and the setDarkMode function, which is used to toggle the dark mode.

Here is an example of how you can use this hook:

```jsx
import useDarkMode from "./useDarkMode"
import "./body.css"

export default function DarkModeComponent() {
  const [darkMode, setDarkMode] = useDarkMode()

  return (
    <button
      onClick={() => setDarkMode(prevDarkMode => !prevDarkMode)}
      style={{
        border: `1px solid ${darkMode ? "white" : "black"}`,
        background: "none",
        color: darkMode ? "white" : "black",
      }}
    >
      Toggle Dark Mode
    </button>
  )
}
```

```css
body.dark-mode {
  background-color: #333;
}
```

## 8. useCopyToClipboard

```jsx
import { useState } from "react"
import copy from "copy-to-clipboard"

export default function useCopyToClipboard() {
  const [value, setValue] = useState()
  const [success, setSuccess] = useState()

  const copyToClipboard = (text, options) => {
    const result = copy(text, options)
    if (result) setValue(text)
    setSuccess(result)
  }

  return [copyToClipboard, { value, success }]
}
```
`useCopyToClipboard` allows you to copy text to the clipboard. First, the hook uses the `useState` hook to track the text being copied and whether the copy was successful. Then, it exports a single function, `copyToClipboard`, which, when called, will copy the provided text to the clipboard.

The hook also has two state values, **value** and **success**, that can be destructured from the hook's return value. The value keeps track of the text copied to the clipboard, and success keeps track of whether the copy was successful.

Here is an example of how you can use this hook:

```jsx
import useCopyToClipboard from "./useCopyToClipboard"

export default function CopyToClipboardComponent() {
  const [copyToClipboard, { success }] = useCopyToClipboard()

  return (
    <>
      <button onClick={() => copyToClipboard("This was copied")}>
        {success ? "Copied" : "Copy Text"}
      </button>
      <input type="text" />
    </>
  )
}
```
This hook can be helpful in situations where you want to allow the user to copy text from your application to the clipboard. For example, you might use it to enable the user to copy a coupon code or a referral link to their clipboard.

## 9. useCookie

```jsx
import { useState, useCallback } from "react"
import Cookies from "js-cookie"

export default function useCookie(name, defaultValue) {
  const [value, setValue] = useState(() => {
    const cookie = Cookies.get(name)
    if (cookie) return cookie
    Cookies.set(name, defaultValue)
    return defaultValue
  })

  const updateCookie = useCallback(
    (newValue, options) => {
      Cookies.set(name, newValue, options)
      setValue(newValue)
    },
    [name]
  )

  const deleteCookie = useCallback(() => {
    Cookies.remove(name)
    setValue(null)
  }, [name])

  return [value, updateCookie, deleteCookie]
}
```
`useCookie` is a custom hook that uses the `js-cookie` library to interact with cookies. It allows you to `get`, `set`, and `delete` a specific cookie by name. 

The hook takes two parameters: the **cookie's name** and a **default** value. 

When the hook is first called, it attempts to get the value of the cookie. It will set the cookie with the default value if it's not present. The hook returns an array with three elements: the **value of the cookie**, a function for **updating the cookie**, and a function for **deleting the cookie**. 

The updateCookie function takes a new value and options to pass to the `js-cookie` set method. The **deleteCookie** function takes no parameter and deletes the cookie using the js-cookie remove method.

Here is an example of how you can use this hook:

```jsx
import useCookie from "./useCookie"

export default function CookieComponent() {
  const [value, update, remove] = useCookie("name", "John")

  return (
    <>
      <div>{value}</div>
      <button onClick={() => update("Sally")}>Change Name To Sally</button>
      <button onClick={remove}>Delete Name</button>
    </>
  )
}
```
This hook can be used in any component where you must interact with cookies, such as storing user preferences or authentication tokens.

## 10. useTranslation

```json
{
  "hi": "Hello",
  "bye": "Goodbye",
  "nested": { "value": "Test" }
}
```

```js
export * as en from "./en.json"
export * as sp from "./sp.json"
```

```json
{
  "hi": "Hola"
}
```

```jsx
import { useLocalStorage } from "../8-useStorage/useStorage"
import * as translations from "./translations"

export default function useTranslation() {
  const [language, setLanguage] = useLocalStorage("language", "en")
  const [fallbackLanguage, setFallbackLanguage] = useLocalStorage(
    "fallbackLanguage",
    "en"
  )

  const translate = key => {
    const keys = key.split(".")

    return (
      getNestedTranslation(language, keys) ??
      getNestedTranslation(fallbackLanguage, keys) ??
      key
    )
  }

  return {
    language,
    setLanguage,
    fallbackLanguage,
    setFallbackLanguage,
    t: translate,
  }
}

function getNestedTranslation(language, keys) {
  return keys.reduce((obj, key) => {
    return obj?.[key]
  }, translations[language])
}
```
This custom hook provides an easy way to add **internationalization** (i18n) to a React application. It uses the `useLocalStorage`(explained in first part) hook to keep the language and fallback language settings in the browser's local storage so that the user's language preference can be remembered between sessions. 

In addition, the hook exports an object with the following properties:
- **Language**: The currently selected language.

- **setLanguage**: A function that allows you to change the selected language.

- **fallbackLanguage**: The fallback language that will be used if a translation is not found in the selected language.

- **setFallbackLanguage**: A function that allows you to change the fallback language.

- **t**: A function that takes a key as an argument and returns the corresponding translation in the selected or fallback language, if available.

The hook uses translations from the ./translations file, which should contain an object for each language that maps keys to translations. If a translation is not found in the selected language, the hook will try to find it in the fallback language. It will return the key itself if it's not found in either.

Here is an example of how you can use this hook:

```jsx
import useTranslation from "./useTranslation"

export default function TranslationComponent() {
  const { language, setLanguage, setFallbackLanguage, t } = useTranslation()

  return (
    <>
      <div>{language}</div>
      <div>{t("hi")}</div>
      <div>{t("bye")}</div>
      <div>{t("nested.value")}</div>
      <button onClick={() => setLanguage("sp")}>Change To Spanish</button>
      <button onClick={() => setLanguage("en")}>Change To English</button>
      <button onClick={() => setFallbackLanguage("sp")}>Change FB Lang</button>
    </>
  )
}
```
This hook can be used in any React application where you need to support multiple languages. For example, you can use the `t` function to translate strings in your components and use the language and fallbackLanguage properties to change the language of your application.

## 11. useOnlineStatus

```jsx
import { useState } from "react"
import useEventListener from "../13-useEventListener/useEventListener"

export default function useOnlineStatus() {
  const [online, setOnline] = useState(navigator.onLine)

  useEventListener("online", () => setOnline(navigator.onLine))
  useEventListener("offline", () => setOnline(navigator.onLine))

  return online
}
```
This hook detects the online status of the user. It uses the useState hook from React to store the current online status and the useEventListener(explained in the first part) hook to listen for changes in the user's online status.

The hook uses the **navigator.onLine** property to check the current online status when the component loads and sets the online state variable accordingly. Then, it uses the **useEventListener** hook to listen for changes in the **online** and **offline** events, which are fired when the user goes **online** or **offline**.

When either of these events occurs, it updates the online state variable by calling `setOnline`(**navigator.onLine**). The hook then returns the current value of the online state variable, which can be used in the component to determine whether the user is currently online or offline.

Here is an example of how you can use this hook:

```jsx
import useOnlineStatus from "./useOnlineStatus"

export default function OnlineStatusComponent() {
  const online = useOnlineStatus()

  return <div>{online.toString()}</div>
}
```
You can use this hook in any component where you need to know whether the user is currently online or offline, for example, to show a message to the user if they are offline or to disable certain functionality.

## 12. useRenderCount

```jsx
import { useEffect, useRef } from "react"

export default function useRenderCount() {
  const count = useRef(1)
  useEffect(() => count.current++)
  return count.current
}
```
This custom Hook allows you to track the number of times a component has been rendered. It uses the `useEffect` and `useRef` hooks from React. The `useRef` hook creates a **ref** with an initial value of **1**, which will keep track of the number of renders. The `useEffect` hook is then used to increment the count ref on every render. Finally, the Hook returns the current count, which can be displayed in the component.

Here is an example of how you can use this hook:

```jsx
import useRenderCount from "./useRenderCount"
import useToggle from "../1-useToggle/useToggle"

export default function RenderCountComponent() {
  const [boolean, toggle] = useToggle(false)

  const renderCount = useRenderCount()

  return (
    <>
      <div>{boolean.toString()}</div>
      <div>{renderCount}</div>
      <button onClick={toggle}>Toggle</button>
    </>
  )
}
```

## 13. useDebugInformation

```jsx
import { useEffect, useRef } from "react"
import useRenderCount from "../27-useRenderCount/useRenderCount"

export default function useDebugInformation(componentName, props) {
  const count = useRenderCount()
  const changedProps = useRef({})
  const previousProps = useRef(props)
  const lastRenderTimestamp = useRef(Date.now())

  const propKeys = Object.keys({ ...props, ...previousProps })
  changedProps.current = propKeys.reduce((obj, key) => {
    if (props[key] === previousProps.current[key]) return obj
    return {
      ...obj,
      [key]: { previous: previousProps.current[key], current: props[key] },
    }
  }, {})
  const info = {
    count,
    changedProps: changedProps.current,
    timeSinceLastRender: Date.now() - lastRenderTimestamp.current,
    lastRenderTimestamp: lastRenderTimestamp.current,
  }

  useEffect(() => {
    previousProps.current = props
    lastRenderTimestamp.current = Date.now()
    console.log("[debug-info]", componentName, info)
  })

  return info
}
```
`useDebugInformation` is a custom React hook that logs information about a component's render. It uses two arguments, a `componentName` string, and a `props` object. 

The hook uses the `useEffect` and `useRef` hooks from the React library to track the number of renders, changes in props, and the time since the last render. When the component re-renders, the hook will log information about the component's render, including the component name, render count, changed props, time since the last render, and final render timestamp.

Here is an example of how you can use this hook:

```jsx
import useDebugInformation from "./useDebugInformation"
import useToggle from "../1-useToggle/useToggle"
import { useState } from "react"

export default function DebugInformationComponent() {
  const [boolean, toggle] = useToggle(false)
  const [count, setCount] = useState(0)

  return (
    <>
      <ChildComponent boolean={boolean} count={count} />
      <button onClick={toggle}>Toggle</button>
      <button onClick={() => setCount(prevCount => prevCount + 1)}>
        Increment
      </button>
    </>
  )
}

function ChildComponent(props) {
  const info = useDebugInformation("ChildComponent", props)

  return (
    <>
      <div>{props.boolean.toString()}</div>
      <div>{props.count}</div>
      <div>{JSON.stringify(info, null, 2)}</div>
    </>
  )
}
```
The hook can be used in any functional component to log this information for debugging or monitoring purposes.
Note that `useToggle` hook is being used here, which I explained in the first part. 

## 14. useHover

```jsx
import { useState } from "react"
import useEventListener from "../13-useEventListener/useEventListener"

export default function useHover(ref) {
  const [hovered, setHovered] = useState(false)

  useEventListener("mouseover", () => setHovered(true), ref.current)
  useEventListener("mouseout", () => setHovered(false), ref.current)

  return hovered
}
```
This hook lets you track whether an element is currently being hovered by the user's mouse. The hook takes a single argument, **ref**, which refers to the element you want to track hover events for. 

The hook uses the `useState` hook to track whether the element is currently being hovered over and the `useEventListener`(explained in first part) hook to listen for `mouseover` and `mouseout` events on the element. When a mouseover event occurs, the state is true, indicating that the element is being hovered over. When a mouseout event occurs, the state is set to false, indicating that the element is no longer being hovered over. 

Finally, the hook returns the current hovered state, which can be used to control the appearance or behavior of the element. For example, this hook can track whether the user is hovering over a specific element on the page.

Here is an example of how you can use this hook:

```jsx
import { useRef } from "react"
import useHover from "./useHover"

export default function HoverComponent() {
  const elementRef = useRef()
  const hovered = useHover(elementRef)

  return (
    <div
      ref={elementRef}
      style={{
        backgroundColor: hovered ? "blue" : "red",
        width: "100px",
        height: "100px",
        position: "absolute",
        top: "calc(50% - 50px)",
        left: "calc(50% - 50px)",
      }}
    />
  )
}
```

## 15. useLongPress

```jsx
import useEventListener from "../13-useEventListener/useEventListener"
import useTimeout from "../2-useTimeout/useTimeout"
import useEffectOnce from "../20-useEffectOnce/useEffectOnce"

export default function useLongPress(ref, cb, { delay = 250 } = {}) {
  const { reset, clear } = useTimeout(cb, delay)
  useEffectOnce(clear)

  useEventListener("mousedown", reset, ref.current)
  useEventListener("touchstart", reset, ref.current)

  useEventListener("mouseup", clear, ref.current)
  useEventListener("mouseleave", clear, ref.current)
  useEventListener("touchend", clear, ref.current)
}
```
`useLongPress` hook allows you to detect a long press on a specific element using a combination of event listeners custom hook(which I've already explained) and the `useTimeout` hook. When the element specified by the ref is pressed down, it starts a timer with the specified delay, and when the press is released before the delay expires, the timer is cleared. However, if the press is held for longer than the delay, the callback function passed in is executed.

Here is an example of how you can use this hook:

```jsx
import { useRef } from "react"
import useLongPress from "./useLongPress"

export default function LongPressComponent() {
  const elementRef = useRef()
  useLongPress(elementRef, () => alert("Long Press"))

  return (
    <div
      ref={elementRef}
      style={{
        backgroundColor: "red",
        width: "100px",
        height: "100px",
        position: "absolute",
        top: "calc(50% - 50px)",
        left: "calc(50% - 50px)",
      }}
    />
  )
}
```
This hook can be used in any component where you want to detect a long press event on a specific element, for example, a button.

---

## Conclusion
In conclusion, custom hooks provide a powerful and flexible way for developers to share logic across their React components. They allow for easy reuse and organization of code, making it easier to reason about and manage the state and behavior of an element. In addition, with hooks, developers can now abstract away complex logic, making their components more focused and easier to test. The hooks provided in this article are just a few examples of what can be accomplished with hooks, and there are many more possibilities to explore. The growing popularity of hooks in the React community is a testament to their utility. They will likely be an essential tool for developers in their React projects.