一、是什么

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

至于为什么引入hook,官方给出的动机是解决长时间使用和维护react过程中常遇到的问题,例如:

  • 难以重用和共享组件中的与状态相关的逻辑
  • 逻辑复杂的组件难以开发与维护,当我们的组件需要处理多个互不相关的 local state 时,每个生命周期函数中可能会包含着各种互不相关的逻辑在里面
  • 类组件中的this增加学习成本,类组件在基于现有工具的优化上存在些许问题
  • 由于业务变动,函数组件不得不改为类组件等等

在以前,函数组件也被称为无状态的组件,只负责渲染的一些工作

因此,现在的函数组件也可以是有状态的组件,内部也可以维护自身的状态以及做一些逻辑方面的处理

二、有哪些

上面讲到,Hooks让我们的函数组件拥有了类组件的特性,例如组件内的状态、生命周期

最常见的hooks有如下:

  • useState
  • useEffect
  • 其他

useState

首先给出一个例子,如下:

import React, { useState } from 'react';

function Example() {
// 声明一个叫 "count" 的 state 变量
const [count, setCount] = useState(0); return (
<div>
<p>You clicked {count} times</p >
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}

在函数组件中通过useState实现函数内部维护state,参数为state默认的值,返回值是一个数组,第一个值为当前的state,第二个值为更新state的函数

该函数组件等价于的类组件如下:

class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
} render() {
return (
<div>
<p>You clicked {this.state.count} times</p >
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>
</div>
);
}
}

从上述两种代码分析,可以看出两者区别:

  • state声明方式:在函数组件中通过 useState 直接获取,类组件通过constructor 构造函数中设置

  • state读取方式:在函数组件中直接使用变量,类组件通过this.state.count的方式获取

  • state更新方式:在函数组件中通过 setCount 更新,类组件通过this.setState()

总的来讲,useState 使用起来更为简洁,减少了this指向不明确的情况

useEffect

useEffect可以让我们在函数组件中进行一些带有副作用的操作

同样给出一个计时器示例:

class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
} componentDidMount() {
document.title = `You clicked ${this.state.count} times`;
}
componentDidUpdate() {
document.title = `You clicked ${this.state.count} times`;
} render() {
return (
<div>
<p>You clicked {this.state.count} times</p >
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>
</div>
);
}
}

从上面可以看见,组件在加载和更新阶段都执行同样操作

而如果使用useEffect后,则能够将相同的逻辑抽离出来,这是类组件不具备的方法

对应的useEffect示例如下:

import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0); useEffect(() => { document.title = `You clicked ${count} times`; });
return (
<div>
<p>You clicked {count} times</p >
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}

useEffect第一个参数接受一个回调函数,默认情况下,useEffect会在第一次渲染和更新之后都会执行,相当于在componentDidMountcomponentDidUpdate两个生命周期函数中执行回调

如果某些特定值在两次重渲染之间没有发生变化,你可以跳过对 effect 的调用,这时候只需要传入第二个参数,如下:

useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]); // 仅在 count 更改时更新

上述传入第二个参数后,如果 count 的值是 5,而且我们的组件重渲染的时候 count 还是等于 5,React 将对前一次渲染的 [5] 和后一次渲染的 [5] 进行比较,如果是相等则跳过effects执行

回调函数中可以返回一个清除函数,这是effect可选的清除机制,相当于类组件中componentwillUnmount生命周期函数,可做一些清除副作用的操作,如下:

useEffect(() => {
function handleStatusChange(status) {
setIsOnline(status.isOnline);
} ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
};
});

所以, useEffect相当于componentDidMountcomponentDidUpdate 和 componentWillUnmount 这三个生命周期函数的组合

其它 hooks

在组件通信过程中可以使用useContextrefs学习中我们也用到了useRef获取DOM结构......

还有很多额外的hooks,如:

  • useReducer
  • useCallback
  • useMemo
  • useRef

三、解决什么

通过对上面的初步认识,可以看到hooks能够更容易解决状态相关的重用的问题:

  • 每调用useHook一次都会生成一份独立的状态

  • 通过自定义hook能够更好的封装我们的功能

编写hooks为函数式编程,每个功能都包裹在函数中,整体风格更清爽,更优雅

hooks的出现,使函数组件的功能得到了扩充,拥有了类组件相似的功能,在我们日常使用中,使用hooks能够解决大多数问题,并且还拥有代码复用机制,因此优先考虑hooks

参考文献

  • https://zh-hans.reactjs.org/docs/hooks-state.html
  • https://zh-hans.reactjs.org/docs/hooks-effect.html
  • https://www.cnblogs.com/lalalagq/p/9898531.html

React Hooks的理解,React Hooks有哪些,解决了什么问题的更多相关文章

  1. 理解 React Hooks 心智模型:必须按顺序、不能在条件语句中调用的规则

    前言 自从 React 推出 hooks 的 API 后,相信大家对新 API 都很喜欢,但是它对你如何使用它会有一些奇怪的限制.比如,React 官网介绍了 Hooks 的这样一个限制: 不要在循环 ...

  2. 理解 React Hooks

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由志航发表于云+社区专栏 TL;DR 一句话总结 React Hooks 就是在 react 函数组件中,也可以使用类组件(classe ...

  3. React Hooks的理解

    一.是什么 Hook 是 React 16.8 的新增特性.它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性 至于为什么引入hook,官方给出的动机是解决长时间使 ...

  4. React劲爆新特性Hooks 重构去哪儿网火车票PWA

    React劲爆新特性Hooks 重构去哪儿网火车票PWA 获取课程资料链接:点击这里获取 本课程先带你细数最近一年来React的新特性,如Hooks.Redux API,让你从头理解Hooks对传统R ...

  5. React函数类组件及其Hooks学习

    目录 函数类组件 函数式组件和类式组件的区别: 为什么要使用函数式组件? Hooks概念及常用的Hooks 1. useState: State的Hook 语法 useState()说明: setXx ...

  6. 从Mixin到hooks,谈谈对React16.7.0-alpha中即将引入的hooks的理解

      为了实现分离业务逻辑代码,实现组件内部相关业务逻辑的复用,在React的迭代中针对类组件中的代码复用依次发布了Mixin.HOC.Render props等几个方案.此外,针对函数组件,在Reac ...

  7. 深入理解React(二) —— 数据流和事件原理

    版权声明:本文由左明原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/158 来源:腾云阁 https://www.qclou ...

  8. 深入理解React、Redux

    深入理解React.ReduReact+Redux非常精炼,良好运用将发挥出极强劲的生产力.但最大的挑战来自于函数式编程(FP)范式.在工程化过程中,架构(顶层)设计将是一个巨大的挑战.要不然做出来的 ...

  9. React 和 Redux理解

    学习React有一段时间了,但对于Redux却不是那么理解.网上看了一些文章,现在把对Redux的理解总结如下 从需求出发,看看使用React需要什么 1. React有props和state pro ...

  10. 对 React Context 的理解以及应用

    在React的官方文档中,Context被归类为高级部分(Advanced),属于React的高级API,但官方并不建议在稳定版的App中使用Context. 很多优秀的React组件都通过Conte ...

随机推荐

  1. Axios 类似于for循环发送批量请求{:axios.all axios.spread}。

    Axios的请求都是异步的!不能用for循环遍历去批量发送请求 那如果我们需要类似与这样的请求怎么办呢 for(let i =0;i<array.length;i++){ axios.post( ...

  2. 3 c++编程-提高篇-模版

    ​ 重新系统学习c++语言,并将学习过程中的知识在这里抄录.总结.沉淀.同时希望对刷到的朋友有所帮助,一起加油哦!  生命就像一朵花,要拼尽全力绽放!死磕自个儿,身心愉悦!  系列文章列表: 1 c+ ...

  3. 微信小程序实战,基于vue2实现瀑布流

    1.什么是瀑布流呢? 瀑布流,又称瀑布流式布局.是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部. 瀑布流对于图片的展现, ...

  4. 【每日一题】【排序sort重载】【工具类】2021年12月23日-31. 下一个排列

    实现获取 下一个排列 的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列(即,组合出下一个更大的整数). 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). 必须 ...

  5. org.apache.poi.openxml4j.exceptions.OLE2NotOfficeXmlFileException: The supplied data appears to be in the OLE2 Format. You are calling the part of POI that deals with OOXML (Office Open XML) Documents

    异常:org.apache.poi.openxml4j.exceptions.OLE2NotOfficeXmlFileException: The supplied data appears to b ...

  6. Safari浏览器对SVG中的<foreignObject>标签支持不友好,渲染容易错位

    在 svg 中需要写一个 markdown 编辑器,需要用到 <foreignObject> 绘制来html,编辑器选择了 simplemde.大致html部分结构如下,<markd ...

  7. 实践GoF的23种设计模式:命令模式

    摘要:命令模式可将请求转换为一个包含与请求相关的所有信息的对象, 它能将请求参数化.延迟执行.实现 Undo / Redo 操作等. 本文分享自华为云社区<[Go实现]实践GoF的23种设计模式 ...

  8. [图像处理] YUV图像处理入门4

    9 yuv420图像截取 本程序中的函数主要是对YUV420P视频数据流的第一帧图像进行截取.类似opencv中的rect函数,函数的代码如下所示: /** * @file 9 yuv_clip.cp ...

  9. Pytorch基础-tensor数据结构

    torch.Tensor Tensor 数据类型 Tensor 的属性 view 和 reshape 的区别 Tensor 与 ndarray 创建 Tensor 传入维度的方法 参考资料 torch ...

  10. 基于Linux下的Ubuntu操作系统常用命令

    一 .linux操作系统的特点 1.linux下一切皆文件 2.linux系统就像一个倒置数 3.linux系统支持多用户.多任务 二. Ubuntu --"乌班图"操作系统 Ub ...