/
useHover.js
37 lines (30 loc) · 1.29 KB
/
useHover.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import { useState, useRef, useCallback } from "react";
// Hook (copied from https://gist.github.com/gragland/a32d08580b7e0604ff02cb069826ca2f)
export default function useHover() {
const [value, setValue] = useState(false);
// Wrap in useCallback so we can use in dependencies below
const handleMouseOver = useCallback(() => setValue(true), []);
const handleMouseOut = useCallback(() => setValue(false), []);
// Keep track of the last node passed to callbackRef
// so we can remove its event listeners.
const ref = useRef();
// Use a callback ref instead of useEffect so that event listeners
// get changed in the case that the returned ref gets added to
// a different element later. With useEffect, changes to ref.current
// wouldn't cause a rerender and thus the effect would run again.
const callbackRef = useCallback(
(node) => {
if (ref.current) {
ref.current.removeEventListener("mouseover", handleMouseOver);
ref.current.removeEventListener("mouseout", handleMouseOut);
}
ref.current = node;
if (ref.current) {
ref.current.addEventListener("mouseover", handleMouseOver);
ref.current.addEventListener("mouseout", handleMouseOut);
}
},
[handleMouseOver, handleMouseOut]
);
return [callbackRef, value];
}