React Hooks 钩子特性
人在身处逆境时,适应环境的能力实在惊人。人可以忍受不幸,也可以战胜不幸,因为人有着惊人的潜力,只要立志发挥它,就一定能渡过难关。
Hooks 是 React 16.8 的新增特性。它可以让你在不编写 class 组件的情况下使用 state 以及其他的 React 特性。
React Hooks 表现形式是以 use
开头的函数被称为 Hook。useState
是 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
useLayoutEffect
是 useEffect
的一个版本,在浏览器重新绘制屏幕之前触发。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 做出的更改一起被一次性渲染到屏幕上,只有一次回流、重绘的代价。
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,它可以让你读取类似于 Promise 或 context 的资源的值。
7. 其他 Hook
这些 Hook 主要对库作者有用,而不常用于应用程序代码。
useDebugValue
允许在 React 开发者工具中为自定义 Hook 添加一个标签。
useId
允许组件绑定一个唯一 ID,其通常与可访问性 API 一起使用。
useSyncExternalStore
允许一个组件订阅一个外部 store。
8. 自定义 Hooks
当我们想在两个函数之间共享逻辑时,我们会把它提取到第三个函数中。即抽离复用 js 逻辑,让结构更加清晰,符合函数式编程思想。
必须以 'use' 开头吗?必须如此。这个约定非常重要。不遵循的话,由于无法判断某个函数是否包含对其内部 Hook 的调用,React 将无法自动检查你的 Hook 是否违反了 Hook 的规则。官网主要研究以下几个问题:
- 什么是自定义钩子,如何编写自己的钩子;
- 如何命名和结构化自定义的钩子;
- 何时以及为什么要提取自定义钩子;
- 如何在组件之间重用逻辑;
React Hooks 钩子特性的更多相关文章
- React Hooks新特性学习随笔
React Hooks 是 React 16.8 的新增特性.它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性. 前言 本篇主要以讲几个常用的api为主. 1.u ...
- 使用React Hooks新特性useReducer、useContext替代传统Redux高阶组件案例
当我们使用redux进行数据管理的时候,一般都是在根组件通过Provider的方式引入store,然后在每个子组件中,通过connect的方式使用高阶组件进行连接,这样造成的一个问题是,大量的高阶组件 ...
- React Hooks用法大全
前言 在 React 的世界中,有容器组件和 UI 组件之分,在 React Hooks 出现之前,UI 组件我们可以使用函数,无状态组件来展示 UI,而对于容器组件,函数组件就显得无能为力,我们依赖 ...
- react新特性 react hooks
本文介绍的是react新特性react hooks,本文面向的是有一定react开发经验的小伙伴,如果你对react还不是很熟悉的话我建议你先学习react并多多联系. 首先我们都知道react有3种 ...
- 30分钟精通React今年最劲爆的新特性——React Hooks
你还在为该使用无状态组件(Function)还是有状态组件(Class)而烦恼吗? --拥有了hooks,你再也不需要写Class了,你的所有组件都将是Function. 你还在为搞不清使用哪个生命周 ...
- 关于React Hooks,你不得不知的事
React Hooks是React 16.8发布以来最吸引人的特性之一.在开始介绍React Hooks之前,让咱们先来理解一下什么是hooks.wikipedia是这样给hook下定义的: In c ...
- 如何构建自己的 react hooks
我们组的前端妹子在组内分享时谈到了 react 的钩子,趁此机会我也对我所理解的内容进行下总结,方便更多的同学了解.在 React 的 v16.8.0 版本里添加了 hooks 的这种新的 API,我 ...
- React Hooks究竟是什么呢?
摘要: React Hooks原理解析. 原文:快速了解 React Hooks 原理 译者:前端小智 我们大部分 React 类组件可以保存状态,而函数组件不能? 并且类组件具有生命周期,而函数组件 ...
- React Hooks简单业务场景实战(非源码解读)
前言 React Hooks 是React 16.7.0-alpha 版本推出的新特性.从 16.8.0 开始,React更稳定的支持了这一新特性. 它可以让你在不编写 class 的情况下使用 st ...
- React hooks详解
此篇文章仅是对hooks入门的总结,老鸟略过吧~ React从16.8.X以后增加了一个新特性,react hooks 让我们看看这个新特性又带来了哪些惊喜呢~以下内容我们采取不同方式创建组件来进行对 ...
随机推荐
- 深入探讨安全验证:OAuth2.0、Cookie与Session、JWT令牌、SSO与开放授权平台设计
什么是认证和授权?如何设计一个权限认证框架? 认证和授权是安全验证中的两个重要概念.认证是确认身份的过程,用于建立双方之间的信任关系.只有在认证成功的情况下,双方才可以进行后续的授权操作.授权则是在认 ...
- PicGo+Github图床配置
为了将 PicGo 设置为使用 GitHub 作为图床,您需要先创建一个 GitHub 仓库用于存储图片,然后在 PicGo 中进行相应的配置.您已经创建了一个仓库,所以让我们来配置 PicGo. 安 ...
- iOS越狱后必装软件
iOS越狱后就跟ubuntu没两样了,很多ubuntu下常用的软件都要装一下 openssh 这个软件可以让我们能够登录iphone Apt-get 用这个软件可以安装很多软件,主要是一些工具调试类软 ...
- 用一个示例来学习DockerFile
在Docker的世界里,我们经常会听到Dockerfile这个词.那么,什么是Dockerfile?它如何工作?本文将简要介绍Dockerfile的基本概念,原理以及一些常用的Dockerfile命令 ...
- MySQL实战实战系列 06 全局锁和表锁 :给表加个字段怎么有这么多阻碍?
今天我要跟你聊聊 MySQL 的锁.数据库锁设计的初衷是处理并发问题.作为多用户共享的资源,当出现并发访问的时候,数据库需要合理地控制资源的访问规则.而锁就是用来实现这些访问规则的重要数据结构. 根据 ...
- Redis系列之——Redis介绍安装配置
文章目录 第一章 redis初识 1.1 Redis是什么 1.2 Redis特性(8个) 1.3 Redis单机安装 1.3.1下载安装 1.3.2三种启动方式 1.3.2.1 最简启动 1.3.2 ...
- 【图像处理】如何使用matplotlib 库显示灰度图像为自定义颜色
项目场景 我这里有一张名为airplane.jpg的灰度图像灰度图像 使用 matplotlib 库读取并显示: import matplotlib.pyplot as plt root=" ...
- 一些常见小程序的UI设计分享
外卖优惠券小程序的UI设计 电子商城系统UI分享 A B C
- C#学习笔记--逻辑语句(分支和循环)
逻辑语句 条件分支语句 条件分支语句可以让顺序执行的代码逻辑产生分支,满足对应条件地执行对应代码逻辑. IF语句 //IF语句块 int a=5; if(a>0&&a<15 ...
- CF1363C
题目简化和分析: 首先注意特判 $ x $ 在叶子节点上 ( 即度为 \(1\) ). 因为每人都采用最优策略所以不可能有人执着的为别人开路. 就是不在同一颗子树上挣扎,会从外围不断清理. 但是每步必 ...