5 分钟搞懂面试官必问 React 题
说说对 React Hooks 的理解?解决了什么问题?
一、是什么
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
会在第一次渲染和更新之后都会执行,相当于在componentDidMount
和componentDidUpdate
两个生命周期函数中执行回调
如果某些特定值在两次重渲染之间没有发生变化,你可以跳过对 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
相当于componentDidMount
,componentDidUpdate
和 componentWillUnmount
这三个生命周期函数的组合
其它 hooks
在组件通信过程中可以使用useContext
,refs
学习中我们也用到了useRef
获取DOM
结构......
还有很多额外的hooks
,如:
- useReducer
- useCallback
- useMemo
- useRef
三、解决什么
通过对上面的初步认识,可以看到hooks
能够更容易解决状态相关的重用的问题:
- 每调用useHook一次都会生成一份独立的状态
- 通过自定义hook能够更好的封装我们的功能
编写hooks
为函数式编程,每个功能都包裹在函数中,整体风格更清爽,更优雅
hooks
的出现,使函数组件的功能得到了扩充,拥有了类组件相似的功能,在我们日常使用中,使用hooks
能够解决大多数问题,并且还拥有代码复用机制,因此优先考虑hooks
结语
创作不易,如果对大家有所帮助,希望大家点赞支持,有什么问题也可以在评论区里讨论😄~

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
富文本及编辑器的跨平台方案
一、前言 之前在《富文本编辑器之游戏角色升级 ing》一文中,跟大家分享了富文本编辑器的发展历程、选型技巧和扩展方案。今天将和大家一起聊一聊“富文本及编辑器跨平台方案”那些事。 大家应该注意到了,标题用的是“富文本及编辑器”,而非“富文本编辑器”。也就意味着本文将围绕富文本跨平台和编辑器跨平台两大部分进行介绍。 通过跨平台方案的分享,希望能给有富文本编辑器跨平台相关需求的小伙伴带来一些帮助。 二、为什么要跨平台 对于一个产品来说,用户的需求程度在一定程度上反映了其产品的价值。对于富文本编辑器而言,以WEB 端(PC 浏览器、移动浏览器)、移动端(IOS 应用、Android 应用)、桌面端(windows、macOS)各自为战的系统生态,已经无法满足用户的需求。同时对于研发人员而言,各端都需要大量的资源投入进行重复能力的开发,这无疑是一种资源的消耗。因此越来越多的团队开始寻求突破,建立跨平台的编辑生态,在不同的平台、不同的终端上实现数据互通,展现体验一致的编辑能力。 (图片来源于网络) 上面是比较笼统的概念,举例子说明下: 社交类型的应用 以微博中的场景为例:假如你用电脑网页版微博发布...
- 下一篇
openGauss数据库源码解析系列文章—— 执行器解析(一)
本篇我们开启第七章执行器解析中“7.1 执行器整体架构及代码概览”、“7.2 执行流程”及“7.3 执行算子”的相关精彩内容介绍。 执行器在数据库整个体系结构中起到承上启下的作用,对上承接优化器产生的最优执行计划,并按照执行计划进行流水线式的执行,对底层的存储引擎中的数据进行操作。openGauss数据库将执行的过程抽象成了不同类型的算子,同时结合编译执行、向量化执行、并行执行等方式,组成了全面、高效的执行引擎。本章着重介绍执行器的整体架构、执行模型、各类算子、表达式,以及编译执行和向量化引擎等全新的执行引擎。 7.1 执行器整体架构及代码概览 本节整体介绍执行器的架构和代码。 7.1.1 执行器整体结构 在SQL引擎将用户的查询解析优化成可执行的计划之后,数据库进入查询执行阶段。执行器基于执行计划对相关数据进行提取、运算、更新、删除等操作,以达到用户查询想要实现的目的。 openGauss在行计算引擎的基础上,增加了编译执行引擎和向量化执行引擎,执行器模块架构如图7-1所示。openGauss的执行器采用的是火山模型(volcano model),这是一种经典的流式迭代模型(pipe...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- CentOS8编译安装MySQL8.0.19
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS7设置SWAP分区,小内存服务器的救世主