LifeCycle
- useMount
- useUnmount
- useUnmountedRef
Advanced
- useLatest(返回当前最新值的 Hook)
- useMemoizedFn(持久化 function 的 Hook,与useCallback相比,无需传入依赖项)
- useControllableValue
const [val, setVal] = useControllableValue<string>(props)
- 自动管理
props.value,props.onChange
- useCreation
useCreation(() => new Subject(), []) 缓存实例化对象
- useEventEmitter
- 父子组件可以共享一个事件对象
const event$ = useEventEmitter();
- useReactive
- 内部使用代理对象Proxy,在set中触发强制更新
useUpdate()
State
- useSetState
const [state, setState] = useSetState({a: 1, b: 2});setState({ c: 3 });state会自动合并a,b属性
- useToggle
- useBoolean
- useCookieState
- useLocalStorageState
- 自动设置及获取浏览器localStorage,获取反序列化,设置序列化
- useSessionStorageState
- 自动设置及获取浏览器sessionStorage,获取反序列化,设置序列化
- useDebounce
useDebounce(value, { wait: 500 }) 监听value变化,延迟500ms内部执行setState,返回值state与value一致
- useThrottle
useThrottle(value, { wait: 500 }) 监听value变化,延迟500ms内部执行setState,返回值state与value一致;示例场景:直播聊天弹幕节流展示,每隔300ms更新最新弹幕
- useMap
- useSet
- usePrevious
- 保存上一次状态的 Hook,内部使用
Object.is浅比较,不一致保存上一次值
- useRafState
useRafState适用于需要高性能更新状态的场景,特别是涉及到动画、实时交互或性能优化的情况下。通过利用 requestAnimationFrame,可以更好地控制状态更新的时机,提升用户体验和页面性能
- useSafeState
- 确保在状态更新时考虑组件的挂载状态,避免因为组件卸载而导致的潜在问题,组件已卸载内部不执行
setState
- useGetState
- 比useState新增了一个getState,可以获取当前状态;
const [state, setState, getState] = useGetState<S>(initialState)
- useResetState
- 比useState新增了一个resetState,可以获取当前状态;
const [state, setState, resetState] = useGetState<S>(initialState)
Effect
- useUpdateEffect
- 首次不执行副作用函数,与useEffect用法一致
- useUpdateLayoutEffect
- 首次不执行副作用函数,与useLayoutEffect用法一致
- useAsyncEffect
- useDebounceEffect
- useThrottleEffect
- useDebounceFn
- useThrottleFn
- useDeepCompareEffect
- 用法与 useEffect 一致,但 deps 通过 lodash isEqual 进行深比较
- useDeepCompareLayoutEffect
- 用法与 useLayoutEffect 一致,但 deps 通过 lodash isEqual 进行深比较
- useInterval
- useTimeout
- useRafInterval
- 优先使用requestAnimationFrame,其回调函数是一个递归函数,判断当前时间与开始时间差大于等于delay,则执行定时器;当不支持requestAnimationFrame,使用setInterval
- 好处:页面不渲染将不执行定时器
- useRafTimeout
- 优先使用requestAnimationFrame,其回调函数是一个递归函数,判断当前时间与开始时间差大于等于delay,则执行定时器,并且结束递归;当不支持requestAnimationFrame,使用setTimeout
- 好处:页面不渲染将不执行定时器
- useLockFn
- useUpdate
Dom
- useEventListener
- 优雅的使用 addEventListener,内部eventName,options变化(浅比较),解绑事件并重新绑定事件
- useClickAway
- 监听目标元素外的点击事件,如果
参数目标元素target.contains(event.target),则不触发监听器,参数target支持数组
- useDocumentVisibility
- useDrop & useDrag
- useDrag
- 设置元素属性draggable为true,注册dragstart监听器设置传输数据
event.dataTransfer.setData('custom', JSON.stringify(dataRef.current));
- useDrop
- drop监听器接受数据
event.dataTransfer.getData('custom'),并将数据传入到onDom回调中
- useEventTarget
- 常见表单控件(通过 e.target.value 获取表单值) 的 onChange 跟 value 逻辑封装,支持自定义值转换和重置功能
- useExternal
- 动态注入 JS 或 CSS 资源,useExternal 可以保证资源全局唯一
const status = useExternal(`${jsPath}`, {
js: {
async: true,
},
});
- useTitle
- useFavicon
- useFullscreen
- 选项设置pageFullscreen为false,底层使用screenfull npm包,基于对dom
element.requestFullscreen的封装
- 选项设置pageFullscreen为true,页面全屏,将元素css样式设置为适口100%,
z-index层级可配,默认999999,不使用requestFullscreen原生api
- useHover
- 在mouseenter,mouseleave监听器中设置state
- useMutationObserver
- useInViewport
- mdn文档
- 监听元素是否在可视区,
const [inViewport, thresholdRatio] = useInViewport(target, options),如果页面是基于body滚动,root无需设置
- useKeyPress
- 监听键盘按键,默认监听
keydown事件,内部使用event.keyCode按键别名来代替按键,比如:13表示enter键
- 支持组合键
ctrl.alt.c的监听,当全部按下组合键时,event.ctrlKey,event.altKey为true,event.keyCode为67,满足前面条件时,触发回调
- 另外,支持监听多个键
['0','1','2'];自定义监听方式,useKeyPress第一个参数为函数;以及自定义监听目标对象,默认window
- useLongPress
- 支持pc和mobile,如果设置了
moveThreshold移动阈值,将会监听移动事件(touchmove,mousemove),偏移量不超过阈值,超过300ms,将触发长按事件
- ps:
clearInterval也可以清除setTimeout定时器
- useMouse
- 获取鼠标指针位置,
clientX,clientY,pageX,pageY,screenX,screenY
- 获取指定元素与文档左上角的距离位置,
elementPosX,elementPosX
- 获取指定元素与鼠标指针的相对位置,
elementX === pageX - elementPosX,elementY === pageY - elementPosY
- useResponsive
- 获取并订阅浏览器窗口的响应式信息,内部通过判断视窗宽度,监听视窗
resize事件,返回对应的响应式信息{ xs: boolean, sm: boolean, md: boolean, lg: boolean, xl: boolean }
- useScroll
- 监听元素的滚动位置,
{ left, top },且支持自定义更新
- useSize
- useFocusWithin
- 监听当前焦点是否在某个区域之内,同 css 属性
:focus-within
focusin 事件在捕获阶段冒泡,会从根元素一直冒泡到目标元素,内部监听focusin,focusout事件,在focusout事件处理器中判断currentTarget是否包含relatedTarget,如果不包含设置setIsFocusWithin(false)
Scene
- useInfiniteScroll
- 内部使用useRequest,返回data,loading,error,mutate,cancel(只是忽略接口请求的响应,并不会阻止或取消请求)
- service:返回的数据必须包含 list 数组,类型为 { list: any[], ...rest },data.list的值是每次service请求响应数据list的叠加值
- options.isNoMore:自定义判断是否是没有更多了,参数为service返回的数据,没有更多了滚动将不会请求数据
- hook还会其他变量:loadingMore,noMore,loadMore,loadMoreAsync,reload,reloadAsync
- usePagination
- 内部使用useRequest,对于service入参有要求,返回结果基本与useRequest一致,多了一个pagination对象,用于antd的分页组件
- useDynamicList
- 一个帮助你管理动态列表状态,并能生成唯一 key 的 Hook,每一个listItem对应唯一的一个key
- 可以添加、插入、更新、删除、移动、排序、首位添加、首位移除、重置、合并等,基本包含了数组的常用操作
- 经典应用:类似实现
FormList,EditableProTable组件功能
- useVirtualList
其他库:react-virtualized和react-window
- 提供虚拟化列表能力的 Hook,用于解决展示海量数据渲染时首屏渲染缓慢和滚动卡顿问题
- 实现原理:根据scrollTop找到所处适口顶部的数据元素,然后根据适口高度及顶部元素找到 所处适口底部的数据元素,1、适口内部渲染的数据元素就是 顶部元素到底部元素之间的数据元素(包含顶部和低部元素);2、css设置,list列表元素高度设置为 所有数据列表高度 - scrollTop,marginTop为scrollTop
- 前提:需要知道单个列表项元素高度,或者计算高度的方法
- useHistoryTravel
- 管理状态历史变化记录,方便在历史记录中前进与后退
- value: 当前记录值,setValue: 设置当前记录值,内部保存past,future变量,分别记录历史值列表,以及前进值列表
- 使用go,back,forward方法前进与后退
- useNetwork
window监听online、offline事件,使用navigator.onLine最新值更新online属性
navigator.connection(部分浏览器支持该对象)监听change事件,使用navigator.connection最新值(返回NetworkInformation类型的对象)更新到state中
- useSelections
- 常见联动 Checkbox 逻辑封装,支持多选,单选,全选逻辑,还提供了是否选择,是否全选,是否半选的状态
- 内部使用
selectedSet(Set对象操作方法,add,has,delete),选择中值selected由Array.from(selectedSet)转换而来
- useCountDown
- 一个用于管理倒计时的 Hook
- 参数优先使用剩余时间戳,没有的话传递目标服务端时间(类型为
string | number | Date | Dayjs | null | undefined),倒计时目标时间是不变的,定时器处理器更新倒计时剩余时间戳(目标时间 - 当前时间戳Date.now())
- useCounter
- 管理计数器的 Hook
- 内部提供
inc,dec,set,reset方法,可以设置计数器的最大和最小值
- useTextSelection
- 返回鼠标选中区域的文本,同时返回选中范围
range的DOMRect类型对象(执行range.getClientRects())
- 实际应用:划词翻译,对选中的单词进行翻译,翻译内容使用
Popover组件,包裹一个空元素(fixed定位,设置range.getClientRects()返回的left,top,width,height)
- useWebSocket
- 封装
WebSocket,支持onOpen,onClose,onMessage,onError事件,支持sendMessage发送消息,支持手动连接connect及手动断开连接disconnect