useMouse
简介
useMouse 这个 hook 的作用是可以监听鼠标位置。
借用了lodash的throttle函数实现了节流。
源码实现
const initState = {
screenX: NaN,
screenY: NaN,
clientX: NaN,
clientY: NaN,
pageX: NaN,
pageY: NaN
}
export const useMouse = () => {
const [state, setState] = useState(initState)
const moveFun = useCallback((state) => {
setState(state)
}, [])
const debounceFn = useCallback(
_.throttle(moveFun, 250, {
leading: false,
trailing: true
}),
[changeFun]
)
useEffect(() => {
const handler = (event) => {
const { screenX, screenY, clientX, clientY, pageX, pageY } = event
const newState = {
screenX,
screenY,
clientX,
clientY,
pageX,
pageY
}
debounceFn(newState)
}
window.addEventListener('mousemove', handler)
return () => window.removeEventListener('mousemove', handler)
}, [])
return state
}
如何使用
// 直接使用
const mouse = useMouse()
useClickAway
简介
useClickAway 这个 hook 的作用是可以监听目标元素外的点击事件。
主要使用了原生apicontains判断点击元素是否被包含在指定元素中。
源码实现
const useClickAway = (fn, dom, eventName = 'click') => {
useEffect(() => {
const handler = (event) => {
// 先判断传入的dom对象是否为多个
const doms = Array.isArray(dom) ? dom : [dom]
// 如果点击的对象在传入的dom对象中,直接返回,不执行函数
if (doms.some((dom) => dom.current.contains(event.target))) {
return
}
fn(event)
}
const eventNames = Array.isArray(eventName) ? eventName : [eventName]
eventNames.forEach((eventName) =>
window.addEventListener(eventName, handler)
)
return () =>
eventNames.forEach((eventName) =>
window.removeEventListener(eventName, handler)
)
}, [])
}
如何使用
// 直接使用
useClickAway(() => {
console.log('1111')
}, ref)
// 其他监听任意鼠标事件
useClickAway(() => {
console.log('1111')
}, ref, 'mousemove')
// 监听多个元素外的`点击`事件
useClickAway(() => {
console.log('1111')
}, [ref1,ref2])
useSyncState
简介
useSyncState 这个 hook 的作用是可以获取useState的最新值。
主要是useRef和useState的结合使用
源码实现
export const useSyncState = <T>(
initState?: T
): [{ current: T }, (data: T) => void] => {
const [state, setStateValue] = useState<T>(initState as T)
const stateRef = useRef<T>(state)
const setState = (value: T) => {
stateRef.current = value
setStateValue(value)
}
return [stateRef, setState]
}
如何使用
// 直接使用
const [state,setState] = useSyncState<string>('')
setState('2')
console.log('state.current',state.current) // 2