Skip to main content

All hooks

useHover

Custom hook that tracks whether a DOM element is being hovered over.


Usage

import { useRef } from 'react'

import { useHover } from './useHover'

export default function Component() {
  const hoverRef = useRef(null)
  const isHover = useHover(hoverRef)

  return (
    <div ref={hoverRef}>
      {`The current div is ${isHover ? `hovered` : `unhovered`}`}
    </div>
  )
}

API

function useHover(elementRef: RefObject<T | null>): boolean

Custom hook that tracks whether a DOM element is being hovered over.

Parameters

NameTypeDefault valueDescription
elementRef`RefObject<Tnull>`-

Returns

A boolean value indicating whether the element is being hovered over.

Hook

import { useState } from 'react'
import type { RefObject } from 'react'

import { useEventListener } from '../useEventListener'
import { useIsomorphicLayoutEffect } from '../useIsomorphicLayoutEffect'

/**
 * Custom hook that tracks whether a DOM element is being hovered over.
 * @template T - The type of the DOM element. Defaults to `HTMLElement`.
 * @param {RefObject<T>} elementRef - The ref object for the DOM element to track.
 * @returns {boolean} A boolean value indicating whether the element is being hovered over.
 * @public
 * @see [Documentation](https://usehooks-ts.com/react-hook/use-hover)
 * @example
 * ```tsx
 * const buttonRef = useRef<HTMLButtonElement>(null);
 * const isHovered = useHover(buttonRef);
 * // Access the isHovered variable to determine if the button is being hovered over.
 * ```
 */
export function useHover<T extends HTMLElement = HTMLElement>(
  elementRef: RefObject<T | null>,
): boolean {
  const [value, setValue] = useState<boolean>(false)

  const handleMouseEnter = () => {
    setValue(true)
  }
  const handleMouseLeave = () => {
    setValue(false)
  }

  useEventListener('mouseenter', handleMouseEnter, elementRef)
  useEventListener('mouseleave', handleMouseLeave, elementRef)

  // Reset hover state when the element is removed from the DOM
  useIsomorphicLayoutEffect(() => {
    if (!elementRef.current) {
      setValue(false)
    }
  })

  return value
}