ahooks(3.7.9) 笔记

379 阅读5分钟

LifeCycle

  1. useMount
  2. useUnmount
  3. useUnmountedRef
  • 获取当前组件是否已经卸载的 Hook。

Advanced

  1. useLatest(返回当前最新值的 Hook)
  2. useMemoizedFn(持久化 function 的 Hook,与useCallback相比,无需传入依赖项)
  3. useControllableValue
  • const [val, setVal] = useControllableValue<string>(props)
  • 自动管理 props.valueprops.onChange
  1. useCreation
  • useCreation(() => new Subject(), []) 缓存实例化对象
  1. useEventEmitter
  • 父子组件可以共享一个事件对象const event$ = useEventEmitter();
  1. useReactive
  • 内部使用代理对象Proxy,在set中触发强制更新useUpdate()

State

  1. useSetState
  • const [state, setState] = useSetState({a: 1, b: 2});setState({ c: 3 });state会自动合并a,b属性
  1. useToggle
  2. useBoolean
  3. useCookieState
  • 使用三方模块 js-cookie
  1. useLocalStorageState
  • 自动设置及获取浏览器localStorage,获取反序列化,设置序列化
  1. useSessionStorageState
  • 自动设置及获取浏览器sessionStorage,获取反序列化,设置序列化
  1. useDebounce
  • useDebounce(value, { wait: 500 }) 监听value变化,延迟500ms内部执行setState,返回值state与value一致
  1. useThrottle
  • useThrottle(value, { wait: 500 }) 监听value变化,延迟500ms内部执行setState,返回值state与value一致;示例场景:直播聊天弹幕节流展示,每隔300ms更新最新弹幕
  1. useMap
  • 管理 Map 类型状态的 Hook
  1. useSet
  • 管理 Set 类型状态的 Hook
  1. usePrevious
  • 保存上一次状态的 Hook,内部使用Object.is浅比较,不一致保存上一次值
  1. useRafState
  • useRafState适用于需要高性能更新状态的场景,特别是涉及到动画、实时交互或性能优化的情况下。通过利用 requestAnimationFrame,可以更好地控制状态更新的时机,提升用户体验和页面性能
  1. useSafeState
  • 确保在状态更新时考虑组件的挂载状态,避免因为组件卸载而导致的潜在问题,组件已卸载内部不执行setState
  1. useGetState
  • 比useState新增了一个getState,可以获取当前状态;const [state, setState, getState] = useGetState<S>(initialState)
  1. useResetState
  • 比useState新增了一个resetState,可以获取当前状态;const [state, setState, resetState] = useGetState<S>(initialState)

Effect

  1. useUpdateEffect
  • 首次不执行副作用函数,与useEffect用法一致
  1. useUpdateLayoutEffect
  • 首次不执行副作用函数,与useLayoutEffect用法一致
  1. useAsyncEffect
  • 支持异步副作用函数
  1. useDebounceEffect
  • 为 useEffect 增加防抖的能力
  1. useThrottleEffect
  • 为 useEffect 增加节流的能力
  1. useDebounceFn
  • 用来处理防抖函数的 Hook
  1. useThrottleFn
  • 用来处理函数节流的 Hook
  1. useDeepCompareEffect
  • 用法与 useEffect 一致,但 deps 通过 lodash isEqual 进行深比较
  1. useDeepCompareLayoutEffect
  • 用法与 useLayoutEffect 一致,但 deps 通过 lodash isEqual 进行深比较
  1. useInterval
  • setInterval定时器 Hook
  1. useTimeout
  • setTimeout定时器 Hook
  1. useRafInterval
  • 优先使用requestAnimationFrame,其回调函数是一个递归函数,判断当前时间与开始时间差大于等于delay,则执行定时器;当不支持requestAnimationFrame,使用setInterval
  • 好处:页面不渲染将不执行定时器
  1. useRafTimeout
  • 优先使用requestAnimationFrame,其回调函数是一个递归函数,判断当前时间与开始时间差大于等于delay,则执行定时器,并且结束递归;当不支持requestAnimationFrame,使用setTimeout
  • 好处:页面不渲染将不执行定时器
  1. useLockFn
  • 用于给一个异步函数增加竞态锁,防止并发执行
  1. useUpdate
  • 返回一个函数,调用该函数会强制组件重新渲染

Dom

  1. useEventListener
  • 优雅的使用 addEventListener,内部eventName,options变化(浅比较),解绑事件并重新绑定事件
  1. useClickAway
  • 监听目标元素外的点击事件,如果参数目标元素target.contains(event.target),则不触发监听器,参数target支持数组
  1. useDocumentVisibility
  • 监听页面是否可见
  1. useDrop & useDrag
  • useDrag
    • 设置元素属性draggable为true,注册dragstart监听器设置传输数据event.dataTransfer.setData('custom', JSON.stringify(dataRef.current));
  • useDrop
    • drop监听器接受数据event.dataTransfer.getData('custom'),并将数据传入到onDom回调中
  1. useEventTarget
  • 常见表单控件(通过 e.target.value 获取表单值) 的 onChange 跟 value 逻辑封装,支持自定义值转换和重置功能
  1. useExternal
  • 动态注入 JS 或 CSS 资源,useExternal 可以保证资源全局唯一
  // 加载状态,unset(未设置), loading(加载中), ready(加载完成), error(加载失败)
  const status = useExternal(`${jsPath}`, {
    js: {
      async: true,
    },
  });
  1. useTitle
  • 用于设置页面标题
  1. useFavicon
  • 设置页面的 favicon
  1. useFullscreen
  • 选项设置pageFullscreen为false,底层使用screenfull npm包,基于对domelement.requestFullscreen的封装
  • 选项设置pageFullscreen为true,页面全屏,将元素css样式设置为适口100%,z-index层级可配,默认999999,不使用requestFullscreen原生api
  1. useHover
  • 在mouseenter,mouseleave监听器中设置state
  1. useMutationObserver
  • 封装基于MutationObserverapi的hook,监听子节点,属性,后代节点的变化
  1. useInViewport
  • mdn文档
  • 监听元素是否在可视区,const [inViewport, thresholdRatio] = useInViewport(target, options),如果页面是基于body滚动,root无需设置
  1. useKeyPress
  • 监听键盘按键,默认监听keydown事件,内部使用event.keyCode按键别名来代替按键,比如:13表示enter键
  • 支持组合键ctrl.alt.c的监听,当全部按下组合键时,event.ctrlKey,event.altKeytrue,event.keyCode67,满足前面条件时,触发回调
  • 另外,支持监听多个键['0','1','2'];自定义监听方式,useKeyPress第一个参数为函数;以及自定义监听目标对象,默认window
  1. useLongPress
  • 支持pc和mobile,如果设置了moveThreshold移动阈值,将会监听移动事件(touchmove,mousemove),偏移量不超过阈值,超过300ms,将触发长按事件
  • ps:clearInterval也可以清除setTimeout定时器
  1. useMouse
  • 获取鼠标指针位置,clientX,clientYpageX,pageYscreenX,screenY
  • 获取指定元素与文档左上角的距离位置,elementPosX,elementPosX
  • 获取指定元素与鼠标指针的相对位置,elementX === pageX - elementPosX,elementY === pageY - elementPosY
  1. useResponsive
  • 获取并订阅浏览器窗口的响应式信息,内部通过判断视窗宽度,监听视窗resize事件,返回对应的响应式信息{ xs: boolean, sm: boolean, md: boolean, lg: boolean, xl: boolean }
  1. useScroll
  • 监听元素的滚动位置,{ left, top },且支持自定义更新
  1. useSize
  • 封装基于ResizeObserver api的hook,监听目标元素的尺寸变化{ width, height }
  1. useFocusWithin
  • 监听当前焦点是否在某个区域之内,同 css 属性 :focus-within
  • focusin 事件在捕获阶段冒泡,会从根元素一直冒泡到目标元素,内部监听focusin,focusout事件,在focusout事件处理器中判断currentTarget是否包含relatedTarget,如果不包含设置setIsFocusWithin(false)

Scene

  1. 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
  1. usePagination
  • 内部使用useRequest,对于service入参有要求,返回结果基本与useRequest一致,多了一个pagination对象,用于antd的分页组件
  1. useDynamicList
  • 一个帮助你管理动态列表状态,并能生成唯一 key 的 Hook,每一个listItem对应唯一的一个key
  • 可以添加、插入、更新、删除、移动、排序、首位添加、首位移除、重置、合并等,基本包含了数组的常用操作
  • 经典应用:类似实现FormListEditableProTable组件功能
  1. useVirtualList

其他库:react-virtualizedreact-window

  • 提供虚拟化列表能力的 Hook,用于解决展示海量数据渲染时首屏渲染缓慢和滚动卡顿问题
  • 实现原理:根据scrollTop找到所处适口顶部的数据元素,然后根据适口高度及顶部元素找到 所处适口底部的数据元素,1、适口内部渲染的数据元素就是 顶部元素到底部元素之间的数据元素(包含顶部和低部元素);2、css设置,list列表元素高度设置为 所有数据列表高度 - scrollTop,marginTop为scrollTop
  • 前提:需要知道单个列表项元素高度,或者计算高度的方法
  1. useHistoryTravel
  • 管理状态历史变化记录,方便在历史记录中前进与后退
  • value: 当前记录值,setValue: 设置当前记录值,内部保存past,future变量,分别记录历史值列表,以及前进值列表
  • 使用go,back,forward方法前进与后退
  1. useNetwork
  • window监听onlineoffline事件,使用navigator.onLine最新值更新online属性
  • navigator.connection(部分浏览器支持该对象)监听change事件,使用navigator.connection最新值(返回NetworkInformation类型的对象)更新到state中
  1. useSelections
  • 常见联动 Checkbox 逻辑封装,支持多选,单选,全选逻辑,还提供了是否选择,是否全选,是否半选的状态
  • 内部使用selectedSet(Set对象操作方法,add,has,delete),选择中值selectedArray.from(selectedSet)转换而来
  1. useCountDown
  • 一个用于管理倒计时的 Hook
  • 参数优先使用剩余时间戳,没有的话传递目标服务端时间(类型为string | number | Date | Dayjs | null | undefined),倒计时目标时间是不变的,定时器处理器更新倒计时剩余时间戳(目标时间 - 当前时间戳Date.now()
  1. useCounter
  • 管理计数器的 Hook
  • 内部提供inc,dec,set,reset方法,可以设置计数器的最大和最小值
  1. useTextSelection
  • 返回鼠标选中区域的文本,同时返回选中范围rangeDOMRect类型对象(执行range.getClientRects()
  • 实际应用:划词翻译,对选中的单词进行翻译,翻译内容使用Popover组件,包裹一个空元素(fixed定位,设置range.getClientRects()返回的left,top,width,height)
  1. useWebSocket
  • 封装WebSocket,支持onOpen,onClose,onMessage,onError事件,支持sendMessage发送消息,支持手动连接connect及手动断开连接disconnect