130+ Hooks,解锁React Hooks使用的正确姿势

简介: 130+ Hooks,解锁React Hooks使用的正确姿势

为什么会有 Hook

介绍Hooks之前,首先要给大家说一下React的组件创建方式,一种是类组件,一种是纯函数组件,并且React团队希望,组件不要变成复杂的容器,最好只是数据流的管道。开发者根据需要,组合管道即可。也就是说组件的最佳写法应该是函数,而不是类。。

但是我们知道,在以往开发中类组件纯函数组件的区别是很大的,纯函数组件有着类组件不具备的多种特点,简单列举几条

  • 纯函数组件没有状态
  • 纯函数组件没有生命周期
  • 纯函数组件没有this
  • 只能是纯函数

这就注定,我们所推崇的函数组件,只能做UI展示的功能,涉及到状态的管理与切换,我们不得不用类组件或者redux,但我们知道类组件的也是有缺点的,比如,遇到简单的页面,你的代码会显得很重,并且每创建一个类组件,都要去继承一个React实例,至于Redux,更不用多说,很久之前Redux的作者就说过,“能用React解决的问题就不用Redux”,等等一系列的话。关于React类组件redux的作者又有话说

  • 大型组件很难拆分重构,也很难测试
  • 业务逻辑分散在组件的各个方法之中,导致重复逻辑关联逻辑
  • 组件类引入了复杂的编程模式,比如 renderprops高阶组件

类组件虽然功能齐全却很重,纯函数很轻便却有上文几点重大限制,所以 React 团队设计了 React Hooks,React Hooks 就是加强版的函数组件,我们可以完全不使用 class,就能写出一个全功能的组件

Hook 解决了什么问题

Hook 解决了我们五年来编写和维护成千上万的组件时遇到的各种各样看起来不相关的问题。无论你正在学习 React,或每天使用,或者更愿尝试另一个和 React 有相似组件模型的框架,你都可能对这些问题似曾相识。

React 没有提供将可复用性行为“附加”到组件的途径(例如,把组件连接到 store )。如果你使用过 React 一段时间,你也许会熟悉一些解决此类问题的方案,比如 renderprops高阶组件。但是这类方案需要重新组织你的组件结构,这可能会很麻烦,使你的代码难以理解。如果你在 React DevTools 中观察过 React 应用,你会发现由 providersconsumers高阶组件render props 等其他抽象层组成的组件会形成“嵌套地狱”。尽管我们可以在 DevTools 过滤掉它们,但这说明了一个更深层次的问题:React 需要为共享状态逻辑提供更好的原生途径。

你可以使用 Hook 从组件中提取状态逻辑,使得这些逻辑可以单独测试并复用。Hook 使你在无需修改组件结构的情况下复用状态逻辑。这使得在组件间社区内共享 Hook 变得更便捷。

官方提供了哪些 Hook

如果你刚开始接触 Hook,那么可能需要先自行查看 React 官方文档

  • 基础 Hook
  • useSstate
  • useEffect
  • useContext
  • 额外的 Hook
  • useReducer
  • useCallback
  • useMemo
  • useRef
  • useImperativeHandle
  • useLayoutEffect
  • useDebugValue

这篇文章的重点不会对官方 Hook 的使用做过多的讲解,当然,想要用好 Hook,首先要先把官方提供的这些 Hook 学明白,才能在项目开发的时候如鱼得水,其次就是做一些自定义 Hook 的封装,用来提高开发效率

当然,项目开发总不能遇到一个功能就去封装一个自定义 Hook ,这里为大家推荐两个比较好用的 Hooks 库: aHooksreact-use,这两个库使用在项目开发中真的能大大提高开发效率,可以毫不夸张的说能够降低你的50%的业务代码,告别996

什么是 ahooks

官网: https://ahooks.js.org/zh-CN

ahooks 是一个 React Hooks 库,致力提供常用且高质量的 Hooks。在使用之前,你需要掌握 ReactReact Hooks 基础用法。ahooks 是由蚂蚁 umi 团队、淘系 ice 团队以及阿里体育团队共同建设的 React Hooks 工具库。ahooks 基于 React Hooks 的逻辑封装能力,提供了大量常见好用的 Hooks,可以极大降低代码复杂度,提升开发效率。ahooks 致力成为和 antd/fusion 一样的 React 基础设施,帮助开发者在逻辑层面省去大量的重复工作。

安装

# 安装依赖
npm i ahooks --save
# 使用 Hooks
import { useRequest } from 'ahooks';

有哪些实用 Hooks

  • 🔥异步请求
  • useRequest — 一个强大的管理异步数据请求的 Hook
  • 🔥table
  • useAntdTable— 封装了常用的 antd Formantd Table 联动逻辑,并且同时支持 antd V3 和 V4
  • useFusionTable — 封装了常用的 Fusion FormFusion Table 联动逻辑。
  • 🔥视图类的
  • useDrag & useDrop — 一对帮助你处理在拖拽中进行数据转移的 hooks
  • useDynamicList — 一个帮助你管理列表状态,并能生成唯一 keyHook
  • useSelections — 常见联动 checkbox 逻辑封装,支持多选,单选,全选逻辑,还提供了是否选择,是否全选,是否半选的状态。
  • useVirtualList — 提供虚拟化列表能力的 Hook,用于解决展示海量数据渲染时首屏渲染缓慢和滚动卡顿问题。
  • 🔥副作用
  • useDebounce — 用来处理防抖值的 Hook
  • useDebounceFn — 用来处理防抖函数的 Hook
  • useInterval — 一个可以处理 setInterval 的 Hook
  • useThrottle — 用来处理节流值的 Hook
  • useThrottleFn — 用来处理节流函数的 Hook
  • useTimeout — 一个可以处理 setTimeout 计时器函数的 Hook。
  • 🔥生命周期
  • useDebounceEffect — 为 useEffect 增加防抖的能力。
  • useMount — 只在组件 mount 时执行的 hook。
  • useThrottleEffect — 为 useEffect 增加节流的能力。
  • useTrackedEffect — 在 useEffect 的基础上,追踪触发 effect 的依赖变化。
  • useUnmount — 只在组件 unmount 时执行的 hook。
  • useUnmountedRef — 获取当前组件是否已经卸载的 hook,用于避免因组件卸载后更新状态而导致的内存泄漏
  • useUpdate — 强制组件重新渲染的 hook。
  • useUpdateEffect — 一个只在依赖更新时执行的 useEffect hook。
  • useUpdateLayoutEffect — 一个只在依赖更新时执行的 useLayoutEffect Hook。
  • 🔥状态
  • useUrlState — 一个同步组件内部状态和 query 参数的 hook。
  • useBoolean — 优雅的管理 boolean 值的 Hook。
  • useControllableValue — 使组件的状态即可以自己管理,也可以被外部控制
  • useCookieState — 一个可以将状态持久化存储在 cookie 中的 Hook 。
  • useCountDown — 一个用于管理倒计时的 Hook。
  • useCounter — 一个可以管理 count 的 Hook。
  • useHistoryTravel — 优雅的管理状态变化历史,可以快速在状态变化历史中穿梭 - 前进跟后退。
  • useLocalStorageState — 一个可以将状态持久化存储在 localStorage 中的 Hook 。
  • useMap — 一个可以管理 Map 类型状态的 Hook。
  • useNetwork — 一个可以管理网络连接状态的 Hook。
  • usePrevious — 保存上一次渲染时状态的 Hook。
  • useSessionStorageState — 一个可以将状态持久化存储在 sessionStorage 中的 Hook。
  • useSet — 一个可以管理 Set 类型状态的 Hook。
  • useSetState — 管理 object 类型 state 的 Hooks,用法与 class 组件的 this.setState 基本一致。
  • useToggle — 用于在两个状态值间切换的 Hook。
  • useWebSocket — 用于处理 WebSocket 的 Hook。
  • useWhyDidYouUpdate — 帮助开发者排查是什么改变导致了组件的 rerender
  • 🔥Dom 相关
  • useClickAway — 优雅的管理目标元素外点击事件的 Hook。
  • useDocumentVisibility — 可以获取页面可见状态的 Hook。
  • useEventListener — 优雅使用 addEventListener 的 Hook。
  • useEventTarget — 常见表单控件(通过 e.target.value 获取表单值) 的 onChangevalue 逻辑封装,支持自定义值转换和重置功能。
  • useExternal — 一个用于动态地向页面加载或卸载外部资源的 Hook。
  • useFavicon — 用于设置与切换页面 favicon
  • useFullscreen — 一个用于处理 dom全屏的 Hook。
  • useHover — 一个用于追踪 dom 元素是否有鼠标悬停的 Hook。
  • useInViewport — 一个用于判断 dom 元素是否在可视范围之内的 Hook。
  • useKeyPress — 一个优雅的管理 keyupkeydown 键盘事件的 Hook,支持键盘组合键,定义键盘事件的 keykeyCode 别名输入 。
  • useMouse — 一个跟踪鼠标位置的 Hook。
  • useResponsive — 获取响应式信息。
  • useScroll — 获取元素的滚动状态。
  • useSize — 一个用于监听 dom 节点尺寸变化的 Hook。
  • useTextSelection — 实时获取用户当前选取的文本内容及位置。
  • useTitle — 用于设置页面标题的 Hook。
  • 🔥高级 Hook
  • useCreation — 是 useMemouseRef 的替代品,确保实例不会被重新创建。
  • useEventEmitter — 多组件间事件通知。
  • useLockFn — 给异步函数加锁,防止重复调用。
  • usePersistFn — 持久化 function 的 Hook。
  • useReactive — 提供一种数据响应式的操作体验,定义数据状态不需要写 useState , 直接修改属性即可刷新视图。
  • useSafeState — 用法与 React.useState 完全一样,但是在组件卸载后异步回调内的 setState 不再执行,避免因组件卸载后更新状态而导致的内存泄漏。

什么是 react-use

是一个国外大佬开发,目前 start 25.9K,github 地址: https://github.com/streamich/react-use

安装

# 安装依赖
npm i react-use --save
# 使用 Hooks
import { useBattery  } from 'react-use';

有哪些实用 Hooks

  • 🔥传感器
  • useBattery — 跟踪设备电池状态。
  • useGeolocation — 跟踪用户设备的地理位置状态。
  • useHover and useHoverDirty — 跟踪鼠标悬停某个元素的状态。
  • useIdle — 跟踪用户是否处于非活动状态。
  • useKey, useKeyPress, useKeyboardJs, 和 useKeyPressEvent — 追踪按键。
  • useLocation — 跟踪页面导航栏的位置状态。
  • useMedia — 跟踪 CSS 媒体查询的状态。
  • useMediaDevices — 跟踪连接的硬件设备的状态。
  • useMotion — 跟踪设备的运动传感器的状态。
  • useMouse and useMouseHovered — 跟踪鼠标位置的状态。
  • useNetwork — 跟踪用户的互联网连接状态。
  • useOrientation — 跟踪设备屏幕方向的状态。
  • usePageLeave — 当鼠标离开页面边界时触发。
  • useScroll — 跟踪 HTML 元素的滚动位置。
  • useSize — 跟踪 HTML 元素的维度。
  • useStartTyping — 检测用户何时开始输入。
  • useWindowScroll — 跟踪 窗口 滚动位置。
  • useWindowSize — 跟踪 窗口 尺寸。
  • 🔥用户界面
  • useAudio — 播放音频并公开其控件。
  • useClickAway — 当用户点击目标区域外时触发回调。
  • useCss — 动态调整 CSS。
  • useDrop and useDropArea — 跟踪文件,链接和复制粘贴。
  • useFullscreen — 全屏显示元素或视频。
  • useSpeech — 从文本字符串合成语音。
  • useVideo — 播放视频,跟踪其状态,以及公开播放控件。
  • useWait — UI 的复杂等待管理。
  • 🔥动画效果
  • useRaf — 在每个 requestAnimationFrame 上重新呈现组件。
  • useSpring — 根据弹簧动力学随时间插入数字。
  • useTimeout — 超时后返回true
  • useTween — 重新渲染组件,同时补间 0 到 1 之间的数字。
  • useUpdate — 返回一个回调,在调用时重新呈现组件。
  • 🔥副作用
  • useAsync — 解析一个 async 函数。
  • useAsyncFn — 异步函数的状态管理。
  • useAsyncRetryuseAsync 带有 retry()方法。
  • useBeforeUnload — 当用户尝试重新加载或关闭页面时显示浏览器警报。
  • useCopyToClipboard — 将文本复制到剪贴板。
  • useDebounce — 防抖函数。
  • useFavicon — 设置页面的favicon
  • useLocalStorage — 管理localStorage中的值。
  • useLockBodyScroll — 锁定body元素的滚动。
  • useSessionStorage — 管理sessionStorage中的值。
  • useThrottle and useThrottleFn — 节流一个函数。
  • useTitle — 设置页面标题。
  • 🔥生命周期
  • useEffectOnce — 仅运行一次的修改后的useEffect
  • useEvent — 订阅事件。
  • useLifecycles — 调用mountunmount回调。
  • useRefMounted — 跟踪组件是否已挂载。
  • usePromise — 仅在安装组件时解析promise
  • useLogger — 在组件经历生命周期时登录控制台。
  • useMount — 调用mount回调。
  • useUnmount — 调用unmount回调。
  • useUpdateEffect — 仅在更新时运行一个effect
  • useDeepCompareEffect — 运行一个effect通过深度比较其依赖项。
  • 🔥状态
  • createMemomemoized hooks的工厂钩子。
  • useGetSet — 返回状态 getter get() 而不是原始状态。
  • useGetSetState — 就像 useGetSetuseSetState 有个孩子。
  • useObservable — 跟踪Observable的最新值。
  • useSetState — 创建类似this.setStatesetState方法。
  • useToggle and useBoolean — 跟踪布尔值的状态。
  • useCounter and useNumber — 跟踪数字的状态。
  • useList — 跟踪数组的状态。
  • useMap — 跟踪对象的状态。

以上介绍的两个 Hooks 库,运用在项目开发中可以说是能够减少你的 50% 业务代码,真的告别996,利用更多的时间来学习新的知识,不要做业务开发的傀儡 🎃

当然在我们平时开发过程中,肯定会遇到一些项目中业务逻辑之类的封装或者是以上两个 Hooks 库没有涉及到的场景,这种情况下就需要自己去自定义 Hook 了,千万要记住: 不要因为自己的一时偷懒直接复制代码,复制一时爽,重构火葬场 🔥🔥🔥

自定义 Hook

官方介绍:自定义 Hook 只是将两个函数之间一些共同的代码提取到单独的函数中。自定义 Hook 是一种自然遵循 Hook 设计的约定,而并不是 React 的特性。

没错,就是函数和函数之间的逻辑复用,但是必须要遵循 Hook 的设计约定,不遵循的话,由于无法判断某个函数是否包含对其内部 Hook 的调用,React 将无法自动检查你的 Hook 是否违反了 Hook 的规则。以下是本人封装的以 Modal 的形式来展示错误信息Hook,仅供参考:

import React, { useState, useEffect } from 'react'
import { Modal, Table } from 'antd'
import { ColumnsType } from 'antd/es/table'
interface IData {
  message: string
}
 // 截取两个字符串之间字符
  function str_substr(start, end, str) {
    // 获取开始下标和结束下标
    let firstIndex = str.indexOf(start)
    let lastIndex = str.lastIndexOf(end)
    return str.substring(firstIndex + 1, lastIndex)
  }
const useErrModal = (data: string) => {
  const [dataSource, setDataSource] = useState<Array<IData>>([])
  const tableContainer = () => (
    <Table size={'small'} dataSource={dataSource} columns={columns} pagination={false} />
  )
  const columns: ColumnsType<IData> = [
    {
      title: '错误明细',
      dataIndex: 'message',
      key: 'message'
    }
  ]
  // data 数据按照 [, ] 切割,数据事例 : "数据部分导入失败:[第1行数据检验失败原因:税收编码为必填项且必须为19位的有效编码, 第2行数据检验失败原因:税率为必填项且为0开头的小数且小数点后不能超过5位,税收编码为必填项且必须为19位的有效编码]"
  let splitStr = str_substr('[', ']', data)
  let arr = splitStr.split(', ')
  let list = []
  arr.map((item, key) => {
    list.push({
      message: item
    })
  })
  setDataSource(list)
  Modal.warning({
    title: '错误信息汇总',
    okText: '确定',
    content: tableContainer
  })
}
export default useErrModal

参考资料

[1]ahooks: https://ahooks.js.org/zh-CN

[2]react-use: https://github.com/streamich/react-use

[3]hooks 详解: https://www.jianshu.com/p/d600f749bb19

[4]hooks 官方文档: https://react.docschina.org/docs/hooks-intro.html

相关文章
|
10天前
|
前端开发 JavaScript
React_函数式Hooks和Class比较优缺点
React Hooks与Class组件都能返回JSX并接收props,但Hooks无`this`指向问题,用`useEffect`模拟生命周期,`memo`优化性能,状态更新用`useState`;Class组件通过生命周期方法、`PureComponent`或`shouldComponentUpdate`优化,状态用`this.state`和`this.setState`管理。
23 1
React_函数式Hooks和Class比较优缺点
|
10天前
|
前端开发 JavaScript
React中函数式Hooks之useRef的使用
React中函数式Hooks的useRef用于获取DOM元素的引用,示例代码演示了其基本用法。
26 3
|
10天前
|
前端开发
React中函数式Hooks之useEffect的使用
本文通过示例代码讲解了React中`useEffect` Hook的用法,包括模拟生命周期、监听状态和清理资源。
25 2
React中函数式Hooks之useEffect的使用
|
6天前
|
存储 缓存 前端开发
使用React hooks,些许又多了不少摸鱼时间
该文章详细讲解了React Hooks的各种用法,包括useState、useEffect、useContext等基础Hooks,以及自定义Hooks的创建,并通过实际示例展示了如何利用Hooks简化组件状态管理和副作用操作,从而提高开发效率。
|
9天前
|
前端开发 JavaScript API
深入探索React Hooks与状态管理
深入探索React Hooks与状态管理
27 2
|
10天前
|
缓存 前端开发
React中函数式Hooks之memo、useCallback的使用以及useMemo、useCallback的区别
React中的`memo`是高阶组件,类似于类组件的`PureComponent`,用于避免不必要的渲染。`useCallback` Hook 用于缓存函数,避免在每次渲染时都创建新的函数实例。`memo`可以接收一个比较函数作为第二个参数,以确定是否需要重新渲染组件。`useMemo`用于缓存计算结果,避免重复计算。两者都可以用来优化性能,但适用场景不同:`memo`用于组件,`useMemo`和`useCallback`用于值和函数的缓存。
31 1
|
10天前
|
前端开发
React中函数式Hooks之useState的使用
本文介绍了React中函数式组件的Hooks——`useState`的使用方法。`useState`允许在函数式组件中使用状态,它返回一个数组,其中包含当前状态的值和更新该状态的函数。文章通过示例代码展示了如何声明状态变量和更新状态变量,包括对数值和对象状态的更新。此外,还展示了如何通过点击按钮触发状态更新,实现交互功能。
22 1
|
10天前
|
前端开发
React使用hooks遇到的坑_state中的某几个属性数据变成了空字符
本文讨论了在React使用hooks时遇到的一个问题:state中的某些属性数据变成了空字符。作者通过在修改函数中重新解构赋值来获取最新的state值,解决了因数据更新不及时导致的问题。
24 0
|
10天前
|
缓存 前端开发
React中函数式Hooks之useMemo的使用
React的`useMemo` Hook 用于优化性能,通过记忆返回值避免重复计算。它接收一个函数和一个依赖数组,只有当依赖项改变时,才会重新计算被记忆的值。这可以用于避免在每次渲染时都进行昂贵的计算,或者防止子组件不必要的重新渲染。例如,可以在父组件中使用`useMemo`包裹子组件,以依赖特定的props,从而控制子组件的渲染。
23 0
|
12天前
|
前端开发 JavaScript UED
深入React Hooks与性能优化实践
深入React Hooks与性能优化实践
23 0

热门文章

最新文章

下一篇
无影云桌面