| 1 |
import { useRef, useEffect, useState } from '@wordpress/element' |
| 2 |
|
| 3 |
export function useIsMounted() { |
| 4 |
const isMounted = useRef(false) |
| 5 |
|
| 6 |
useEffect(() => { |
| 7 |
isMounted.current = true |
| 8 |
return () => (isMounted.current = false) |
| 9 |
}) |
| 10 |
return isMounted |
| 11 |
} |
| 12 |
|
| 13 |
export const useIsDevMode = () => { |
| 14 |
const [devMode, setDevMode] = useState(false) |
| 15 |
const check = () => { |
| 16 |
return ( |
| 17 |
window.location.search.indexOf('DEVMODE') > -1 || |
| 18 |
window.location.search.indexOf('LOCALMODE') > -1 |
| 19 |
) |
| 20 |
} |
| 21 |
useEffect(() => { |
| 22 |
const handle = () => setDevMode(check()) |
| 23 |
handle() |
| 24 |
window.addEventListener('popstate', handle) |
| 25 |
return () => { |
| 26 |
window.removeEventListener('popstate', handle) |
| 27 |
} |
| 28 |
}, []) |
| 29 |
return devMode |
| 30 |
} |
| 31 |
|
| 32 |
export const useWhenIdle = (time) => { |
| 33 |
const [userInteracted, setUserInteracted] = useState(true) |
| 34 |
const [idle, setIdle] = useState(false) |
| 35 |
const isMounted = useIsMounted() |
| 36 |
const timerId = useRef() |
| 37 |
|
| 38 |
useEffect(() => { |
| 39 |
const handleMovement = () => setUserInteracted(true) |
| 40 |
const passive = { passive: true } |
| 41 |
window.addEventListener('keydown', handleMovement, passive) |
| 42 |
window.addEventListener('mousemove', handleMovement, passive) |
| 43 |
window.addEventListener('touchmove', handleMovement, passive) |
| 44 |
return () => { |
| 45 |
window.removeEventListener('keydown', handleMovement) |
| 46 |
window.removeEventListener('mousemove', handleMovement) |
| 47 |
window.removeEventListener('touchmove', handleMovement) |
| 48 |
} |
| 49 |
}, []) |
| 50 |
|
| 51 |
useEffect(() => { |
| 52 |
if (!userInteracted) return |
| 53 |
setUserInteracted(false) |
| 54 |
setIdle(false) |
| 55 |
window.clearTimeout(timerId.current) |
| 56 |
timerId.current = window.setTimeout(() => { |
| 57 |
isMounted.current && setIdle(true) |
| 58 |
}, time) |
| 59 |
}, [userInteracted, time, isMounted]) |
| 60 |
|
| 61 |
return idle |
| 62 |
} |
| 63 |
|
| 64 |
/** Dev debugging tool to identify leaky renders: https://usehooks.com/useWhyDidYouUpdate/ */ |
| 65 |
export const useWhyDidYouUpdate = (name, props) => { |
| 66 |
const previousProps = useRef() |
| 67 |
useEffect(() => { |
| 68 |
if (previousProps.current) { |
| 69 |
const allKeys = Object.keys({ ...previousProps.current, ...props }) |
| 70 |
const changesObj = {} |
| 71 |
allKeys.forEach((key) => { |
| 72 |
if (previousProps.current[key] !== props[key]) { |
| 73 |
changesObj[key] = { |
| 74 |
from: previousProps.current[key], |
| 75 |
to: props[key], |
| 76 |
} |
| 77 |
} |
| 78 |
}) |
| 79 |
if (Object.keys(changesObj).length) { |
| 80 |
console.log('[why-did-you-update]', name, changesObj) |
| 81 |
} |
| 82 |
} |
| 83 |
previousProps.current = props |
| 84 |
}) |
| 85 |
} |
| 86 |
|