首页 > 其他分享 >React Hooks 钩子特性及应用场景

React Hooks 钩子特性及应用场景

时间:2024-03-06 16:56:12浏览次数:17  
标签:函数 Hooks React Hook 钩子 组件 useEffect

Hooks 是 React 16.8 的新增特性。它可以让你在不编写 class 组件的情况下使用 state 以及其他的 React 特性。

React Hooks 表现形式是以 use 开头的函数被称为 HookuseState 是 React 提供的一个内置 Hook。你可以在 React API 参考 中找到其他内置的 Hook。你也可以通过组合现有的 Hook 来编写属于你自己的 Hook。

跟普通函数相比,Hook 比普通函数更为严格。你只能在你的组件(或其他 Hook)的顶层调用 Hook。如果你想在一个条件或循环中使用 useState,请提取一个新的组件并在组件内部使用它。

为什么要使用 Hooks?

  • 解决高阶类组件复用,导致代码层级复杂问题。
  • React 组件生命周期的复杂,用于代替生命周期函数。
  • 如果一个类一开始设计成了 function 组件,无状态组件,因为需要状态,又改成了 class 成本高。

1. State Hook

State 让组件“记住”用户输入之类的信息。例如,表单组件可以使用 state 来存储输入值,而图片库组件可以使用 state 来存储所选的图像索引。要给组件添加状态,可以使用以下介绍的钩子之一。

1.1 useState

useState 是一个 React Hook。它允许你向组件添加一个状态变量。模拟类组件的状态管理。

// usss
const [state, setstate] = usestate(initialState)

1.2 useReducer

useReducer 是一个 React Hook,它允许你向组件里面添加一个 reducer,来维护一个状态 state。useReducer 不支持异步处理,异步处理需要借助于 Hooks useEffect。

在单个组件中实现状态管理,理解 useReducer 的使用。

const [state, dispatch] = useReducer(reducer, initialState)

其次配合 useContext 跨级通信。将数据逻辑(即状态管理)从组件中(视图逻辑)分离出来通过外部管理,降低组件耦合度。对于单个组件来说意义不大,但是对于多个组件数据需要共享状态的时候很方便。

2. Context Hook

2.1 useContext

useContext 是一个 React Hook,可以让你读取和订阅组件中的 context。减少组件层级,便于组件跨级通信处理。

useContext 配合 useState、useContext 配合 useReducer。

3. Ref Hooks

Refs 允许组件保存一些不用于呈现(渲染)的信息,比如 DOM 节点或超时 ID。与 state 不同,更新 ref 并不会重新呈现组件。React 提供了 useRef hook 来描述。

3.1 useRef

保存引用值:

const ref = useRef(initialValue)

4. Effect Hooks

Effect 允许组件 连接到外部系统并与之同步。这包括处理网络、浏览器、DOM、动画、使用不同 UI 库编写的 widgets 以及其他非 React 代码。

Effect Hooks 副作用钩子函数很好模拟了类组件的生命周期函数。但是我们知道 Function Component 不存在生命周期,所以不要把 Class Component 的生命周期概念搬过夹试图对号入座。

4.1 useEffect

useEffect 是一个 React Hook,它允许你 连接到外部系统并与之同步

useEffect(setup, dependencies?)

// 处理副作用
useEffect(() => {
// 副作用函数处理代码块 { 比如数据请求,定时器 }
console.log("effect")

return () => {
console.log("cleanup")
// cleanup
// 执行时机:无依赖情况下:组件销毁执行 有依赖情况下:依赖更新和组件销毁的时候
}
}, [ name /* 依赖的状态,如果为空表示不依赖任何状态 */])

依赖:不要对 Dependencies 撒谎,如果你明明在 effect 中使用了某个变量,却没有申明在依赖中,你等于向 React 撒了谎,后果就是,当依赖的变量改变时,useEffect 也不会再次执行,eslint 会报警告。

4.2 useLayoutEffect

useLayoutEffectuseEffect 的一个版本,在浏览器重新绘制屏幕之前触发。useLayoutEffect 内部的代码和所有计划的状态更新阻塞了浏览器重新绘制屏幕。如果过度使用,这会使你的应用程序变慢。如果可能的话,尽量选择 useEffect

然后如果 Effect 一定要阻止浏览器绘制屏幕,使用 useLayoutEffect 替换 useEffect。请注意,绝大多数的 Effect 都不需要这样。只有当在浏览器绘制之前运行 Effect 非常重要的时候才需要如此:例如,在用户看到 tooltip 之前测量并定位它。

4.3 useInsertionEffect

useInsertionEffect 是为 CSS-in-JS 库的作者特意打造的。除非你正在使用 CSS-in-JS 库并且需要注入样式,否则你应该使用 useEffect 或者 useLayoutEffect

4.4 Effect Hooks 之间区别

简单来说就是调用时机不同,useLayoutEFfect 和原来 componentDidMount & componentDidUpdate 一致,在 React 完成 Dom 更新后马上同步调用的代码,即在浏览器重新绘制屏幕之前触发 useLayouteEffect。你可以在这里测量布局。会阻塞页面渲染(渲染树)。

useEffect 是会在整个页面渲染完才会调用的代码。

useInsertionEffect 会在 React 修改 DOM 之前触发。可以在这里插入动态 CSS。

官方建议优先使用 useEffect

However, we recommend starting with useEffect first and only trying useLayoutEffect if that causes a problem.

在实际使用时如果想避免页面抖动(即在 useEffect 里修改 Dom 很有可能出现)的话,可以把需要操作 Dom 的代码放在 useLayoutEffect 里。在这里做点 Dom 操作,这些 Dom 修改会和 react 做出的更改一起被一次性渲染到屏幕上,只有一次回流、重绘的代价。

4. Hooks.png

5. 性能 Hook

5.1 useMemo

useMemo 是一个 React Hook,它在每次重新渲染的时候能够缓存、使用计算的结果。

const cachedValue = useMemo(calculateValue, dependencies)

useMemo(() => first, [second])

记忆纯函数计算结果、跳过组件的重新渲染,记忆一个函数。

对于使用 useMemo 记忆一个函数,这看起来很笨拙!记忆函数很常见,React 有一个专门用于此的内置 Hook。将你的函数包装到 useCallback 而不是 useMemo 中,以避免编写额外的嵌套函数。 即 useCallback 的唯一好处是它可以让你避免在内部编写额外的嵌套函数。它没有做任何其他事情。

5.2 useCallBack

useCallback 是一个允许你在多次渲染中缓存函数的 React Hook。记忆函数,防止因为组件重新渲染,导致组件内部定义的方法被重新创建,起到缓存作用。只有第二个参数依赖项变化了才重新声明一次。如果依赖传入空数组,那么函数第一次创建后就被缓存,这时如果函数定义中的使用了某个状态值改变了,以后调用函数拿到的还是老的值。如果不传第二个参数,每次都会重新声明一次。

const cachedFn = useCallback(fn, dependencies)

和 useMemo 唯一的区别是:useCallback 不会执行第一个参数函数,而是将它返回给你,而 useMemo 会执行第一个参数函数并且将函数执行结果返回给你。所以在前面的例子中,可以返回 handleClick 来达到存储函数的目的。

所以 useCallback 常用记忆事件函数,生成记忆后的事件函数并传递给子组件使用。而 useMemo 更适合经过函数计算得到一个确定的值,比如记忆组件、结果。

5.3 useTransition

useTransition 允许将状态转换标记为非阻塞,并允许其他更新中断它此更新。

5.4 useDeferredValued

useDeferredValue 是一个 React Hook,可以让你延迟更新 UI 的某些部分。

6. 资源 Hook

use 是一个 React Hook,它可以让你读取类似于 Promisecontext 的资源的值。

7. 其他 Hook

这些 Hook 主要对库作者有用,而不常用于应用程序代码。

useDebugValue 允许在 React 开发者工具中为自定义 Hook 添加一个标签。

useId 允许组件绑定一个唯一 ID,其通常与可访问性 API 一起使用。

useSyncExternalStore 允许一个组件订阅一个外部 store。

8. 自定义 Hooks

当我们想在两个函数之间共享逻辑时,我们会把它提取到第三个函数中。即抽离复用 js 逻辑,让结构更加清晰,符合函数式编程思想。

必须以 'use' 开头吗?必须如此。这个约定非常重要。不遵循的话,由于无法判断某个函数是否包含对其内部 Hook 的调用,React 将无法自动检查你的 Hook 是否违反了 Hook 的规则。官网主要研究以下几个问题:

  • 什么是自定义钩子,如何编写自己的钩子;
  • 如何命名和结构化自定义的钩子;
  • 何时以及为什么要提取自定义钩子;
  • 如何在组件之间重用逻辑;

标签:函数,Hooks,React,Hook,钩子,组件,useEffect
From: https://www.cnblogs.com/mounterLove/p/18056942

相关文章

  • React—组件通信
    一、父传子(Props)父组件可以通过props将数据传递给子组件。这是React中最常见的一种方式,适用于父子组件之间的数据传递。{/*组件传递:父传子*/}{/*1.父组件传递数据子组件标签上绑定属性*/}{/*2.子组件接收数据props(props对象里包含了父组件传......
  • React 高阶组件、Render props、hooks 有什么区别?
    这三者是目前react解决代码复用的主要方式:高阶组件(hoc)官方解释:高阶组件(HOC)是React中用于复用组件逻辑的一种高级技巧。HOC自身不是ReactAPI的一部分,它是一种基于React的组合特性而形成的设计模式。简言之,HOC是一种组件的设计模式,HOC接受一个组件和额外的......
  • 自定义Hooks:四个典型的使用场景
    一、如何用好hook要用好ReactHooks,很重要的一点,就是要能够从Hooks的角度去思考问题。要做到这一点其实也不难,就是在遇到一个功能开发的需求时,首先问自己一个问题:这个功能中的哪些逻辑可以抽出来成为独立的Hooks?这样问的目的,是为了让我们尽可能的吧业务陆奥及拆分......
  • React的7个常用Hooks及使用场景(含示例)
    React是一款非常流行的JavaScript库,它提供了许多Hooks,用于管理函数组件的状态和生命周期。下面是React的每个Hooks的使用场景和示例:No1、useStateuseState用于在函数组件中管理状态。它返回一个包含当前状态和一个更新状态的函数的数组。更新状态的函数可以接受一个新的值......
  • Vue Router系列之(十一)两个新的生命周期钩子
    两个新的生命周期钩子​ 缓存路由组件和定时器一起使用时,如果进行了路由跳转,本应触发在beforeDestroy钩子中清除定时器方法,但因为缓存了路由组件,就导致原来的路由组件的beforeDestroy钩子不会被触发,定时器也就不会清除作用:路由组件所独有的两个钩子,用于捕获路由组件的激活状态......
  • React项目升级
    一、前端框架(或者库)升级的原因:a、前端技术更新比较快,需要不断更新保持技术和依赖都和社区同步;b、新版脚手架对性能和开发体验都进行了很多优化,新版脚手架基于社区2021年的相对最优解决方案和依赖。如vite2.0、react17(相比react16版本有了核心实现的重构)等;二、详细描述要升级的......
  • react native工程打包成apk
    react-native工程打包成apk1.生成签名密钥使用jdk自带的keytool生成密钥以管理员身份运行如下命令keytool-genkey-v-keystoremy-test3-key.keystore-aliasmy-key-test3-keyalgRSA-keysize2048-validity10000其中my-test3-key.keystore为生成的密钥库文件(给Andr......
  • React基础-下
    React目录ReactReact表单控制受控表单绑定非受控绑定(React中获取DOM)React组件通信父子通信—父传子props说明特殊的propchildren父子通信—子传父兄弟组件通信使用Context机制跨层级组件通信React副作用管理—useEffect概念useEffect基础使用useEffect依赖说明......
  • react 使用splitChunks 拆分组件,缩小项目体积,加快加载访问速度
    react编写项目引入npm包打包时,总会将一些npm包重复打包的不同的js文件中,可以使用splitChunks进行拆分,降低体积,加快速度1、安装npminstallcustomize-crawebpack-bundle-analyzer2、修改启动命令,在package.json中修改"scripts":{"start":"react-app-rewiredstar......
  • react错误:Uncaught Error: Too many re-renders. React limits the number of renders
    react错误:UncaughtError:Toomanyre-renders.Reactlimitsthenumberofrenderstopreventaninfiniteloop. 信铁寒胜:更改页面数据时未放到useEffect方法内,导致页面一直在刷新。  原因1:错误写法:<divclassName='article_item'onClick={toArticleDetail......