面试题React

1.React Fiber是什么?

在 React V16 将调度算法进行了重构, 将之前的 stack reconciler 重构成新版的 fiber reconciler,变成了具有链表和指针的 单链表树遍历算法。通过指针映射,每个单元都记录着遍历当下的上一步与下一步,从而使遍历变得可以被暂停和重启。

这里我理解为是一种 任务分割调度算法,主要是 将原先同步更新渲染的任务分割成一个个独立的 小任务单位,根据不同的优先级,将小任务分散到浏览器的空闲时间执行,充分利用主进程的事件循环机制。

在react中,主要做了以下的操作:

1.为每个任务增加了优先级,优先级高的任务可以中断低优先级的任务。然后再重新执行优先级低的任务

  1. 增加了异步任务,调用requestIdleCallback api,浏览器空闲的时候执行

  2. dom diff树变成了链表,一个dom对应两个fiber(一个链表),对应两个队列,这都是为找到被中断的任务,重新执行
    ————————————————

链表树遍历算法: 通过 节点保存与映射,便能够随时地进行 停止和重启,这样便能达到实现任务分割的基本前提
任务分割,React 中的渲染更新可以分成两个阶段

reconciliation 阶段: vdom 的数据对比,是个适合拆分的阶段,比如对比一部分树后,先暂停执行个动画调用,待完成后再回来继续比对
Commit 阶段: 将 change list 更新到 dom 上,并不适合拆分,才能保持数据与 UI 的同步。否则可能由于阻塞 UI 更新,而导致数据更新和 UI 不一致的情况。
分散执行: 任务分割后,就可以把小任务单元分散到浏览器的空闲期间去排队执行,而实现的关键是两个新API: requestIdleCallback 与 requestAnimationFrame
低优先级的任务交给requestIdleCallback处理,这是个浏览器提供的事件循环空闲期的回调函数,需要 pollyfill,而且拥有 deadline 参数,限制执行事件,以继续切分任务;
高优先级的任务交给requestAnimationFrame处理。

  • Fiber 其实可以算是一种编程思想,在其它语言中也有许多应用(Ruby Fiber)。
  • 核心思想是 任务拆分和协同,主动把执行权交给主线程,使主线程有时间空挡处理其他高优先级任务。
  • 当遇到进程阻塞的问题时,任务分割、异步调用 和 缓存策略 是三个显著的解决思路。

React 的核心流程可以分为两个部分:

reconciliation (调度算法,也可称为 render)
更新 state 与 props;
调用生命周期钩子;
生成 virtual dom
这里应该称为 Fiber Tree 更为符合;
通过新旧 vdom 进行 diff 算法,获取 vdom change
确定是否需要重新渲染
commit
如需要,则操作 dom 节点更新

2. javascript中的类数组和鸭式辩形

1.什么是类数组?
解释:不是数组, 长的像数组;
类数组本质是一个对象, 只不过是具有如下两个特性的对象:
1)拥有length属性 和数字索引
2)不具有普通数组的操作方法
2.常见的类数组有哪些
arguments
函数参数
HTMLCollection
通过getElementsByTagName和getElementsByClassName选择器筛选出的DOM元素
NodeList
通过querySelectorAll筛选出的NodeList

3.setState到底是异步还是同步?

先给出答案: 有时表现出异步,有时表现出同步

1.setState只在合成事件和钩子函数中是“异步”的,在原生事件和setTimeout 中都是同步的。

2.setState 的“异步”并不是说内部由异步代码实现,其实本身执行的过程和代码都是同步的,只是合成事件和钩子函数的调用顺序在更新之前,导致在合成事件和钩子函数中没法立马拿到更新后的值,形成了所谓的“异步”,当然可以通过第二个参数setState(partialState, callback)中的callback拿到更新后的结果。
3. setState 的批量更新优化也是建立在“异步”(合成事件、钩子函数)之上的,在原生事件和setTimeout 中不会批量更新,在“异步”中如果对同一个值进行多次setState,setState的批量更新策略会对其进行覆盖,取最后一次的执行如果是同时setState多个不同的值,在更新时会对其进行合并批量更新。

4.React context是什么?

来实现跨层级的组件数据传递

其原理主要是通过 React.createContext() 方法创建一个上下文对象,该对象包含了 Provider 和 Consumer 两个属性。Provider 组件可以将需要共享的数据作为 value 传递给子组件,在子组件中可以通过 Consumer 组件获取到这些数据。

当使用 Context 时,React会从当前组件开始往上层查找最近的 Provider,然后通过 contextType 属性或 useContext() 钩子函数获取 Provider 所提供的数据。如果没有找到 Provider,则会使用 createContext() 方法中传入的默认值。

5.描述Flux?

Flux基本概念:

    View: 视图层
    Action(动作):视图层发出的消息(比如mouseClick)
    Dispatcher(派发器):用来接收Actions、执行回调函数
    Store(数据层):用来存放应用的状态,一旦发生变动,就提醒Views要更新页面

Flux 的最大特点,就是数据的"单向流动"。
用户访问 View
View 发出用户的 Action
Dispatcher 收到 Action,要求 Store 进行相应的更新
Store 更新后,发出一个"change"事件
View 收到"change"事件后,更新页面

在这里插入图片描述

6.什么是受控组件?

  • 受控组件(Controlled Components)是指表单元素的值由 React 组件管理并控制的组件。数据变了页面也变了。受控组件更合适,数据驱动是react核心。
  • 非受控组件不是通过数据控制页面内容

7.react中hooks是如何模拟组件的生命周期的?

在函数组件中,可以使用 useEffect Hook 来模拟这些生命周期函数。useEffect 可以接收两个参数:第一个参数是一个回调函数,它会在组件渲染完成后执行,相当于 componentDidMount;第二个参数是一个数组,它可以指定依赖项,只有依赖项发生变化时才会触发回调函数的执行,相当于 componentDidUpdate。

同时,如果在 useEffect 的回调函数中返回一个函数,那么这个返回的函数将会在组件卸载时执行,相当于 componentWillUnmount。

在指定了依赖项的情况下,每次组件重新渲染时,React 都会比较当前的依赖项和上一次的依赖项是否相同。如果它们不同,则会执行 useEffect 的回调函数。

在组件初次渲染时,React 会将之前的依赖项视为 undefined,因此无论依赖项的值是什么,都与之前的依赖项不同。这种情况下,即使指定了依赖项,useEffect 的回调函数仍然会被执行一次,相当于执行了 componentDidMount。

在 useEffect 的回调函数中返回一个函数,该函数将在组件卸载时执行。因此,在该函数中可以进行一些资源的释放操作,例如取消订阅、清除定时器等。注意,该函数需要返回一个清理函数,以确保在组件卸载时执行。

8.React key的作用?

判断元素是新创建的还是被移动的元素,从而减少不必要的元素渲染

9.Refs是什么,如何使用?

允许我们访问 DOM 节点或在 render 方法中创建的 React 元素
何时使用refs:

管理焦点,文本选择或媒体播放。
触发强制动画。
集成第三方 DOM 库。

使用方法:
1.字符串
2、回调函数
3、React.createRef() 创建,并通过 ref 属性附加到 React 元素,当 ref 被传递给 render 中的元素时,对该节点的引用可以在 ref 的 current 属性中被访问。

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();  }
  render() {
    return <div ref={this.myRef} />;  }
}

10.React生命周期?

旧的生命周期
在这里插入图片描述
初始化阶段: 由ReactDOM.render()触发—初次渲染

1. constructor() ---构造器
2. componentWillMount() ---将要挂载
3. render() ---render
4. componentDidMount() ---挂载时

更新阶段: 由组件内部this.setSate()或父组件重新render触发

6. shouldComponentUpdate() ---是否要进行更改数据
7. componentWillUpdate() ---将要更新数据
8. render()
9. componentDidUpdate() ---更新数据

卸载组件: 由ReactDOM.unmountComponentAtNode()触发

componentWillUnmount() ---卸载

在这里插入图片描述初始化阶段: 由ReactDOM.render()触发—初次渲染

1. constructor()
2. getDerivedStateFromProps()
3. render()
4. componentDidMount()

getDerivedStateFromProps()简单翻译过来就是从Props中获得State,所以该函数的功能就是从更新后的props中获取State,它让组件在 props 发生改变时更新它自身的内部 state。

更新阶段: 由组件内部this.setSate()或父组件重新render触发

1. getDerivedStateFromProps()
2. shouldComponentUpdate()
3. render()
4. getSnapshotBeforeUpdate()
5. componentDidUpdate()

卸载组件: 由ReactDOM.unmountComponentAtNode()触发

1. componentWillUnmount()

11.React事件系统?

合成事件 处理了浏览器之间的差异,在上层面向开发者暴露统一的、稳定的、与 DOM 原生事件相同的事件接口。
React 能够从很大程度上干预事件的表现,使其符合自身的需求。

一方面,将事件绑定在document统一管理,防止很多事件直接绑定在原生的dom元素上。造成一些不可控的情况
另一方面, React 想实现一个全浏览器的框架, 为了实现这种目标就需要提供全浏览器一致性的事件系统,以此抹平不同浏览器的差异。

12.React组件理解

声明式渲染:React 使创建交互式 UI 变得轻而易举。为你应用的每一个状态设计简洁的视图,当数据改变时 React 能有效地更新并正确地渲染组件。
组件化:创建拥有各自状态的组件,再由这些组件构成更加复杂的 UI。

13.为什么React会引入JSX?

JSX是js的语法扩展,更好的描述UI应该呈现应有交互的本质形式。
JSX是React.CreacteElement 的语法糖。

14.React 虚拟dom

为什么使用虚拟DOM?
因为操作真实DOM的耗费的性能代价太高,所以react内部使用js实现了一套dom结构,在每次操作在和真实dom之前,使用实现好的diff算法,对虚拟dom进行比较,递归找出有变化的dom节点,然后对其进行更新操作

React.CreacteElement函数返回的一个虚拟DOM,就是一个描述真实DOM的纯JS对象
优点:处理了浏览器兼容性问题,避免用户操作真实DOM
内部经过了xss处理,可以防范xss攻击
容易实现跨平台。
更新的时候实现差异化更新。减少更新dom操作
在初次渲染的时候,其实并不快。在更新的元素内容比较少,可以实现精确更新。不需要把全部的DOM元素删除重添加
缺点:虚拟DOM需要消耗额外的内存
首次渲染其实不快。
$typeof是啥?标识符,表示一个React元素,也就是所谓的虚拟DOM

15.函数组件和类组件的相同点和不同点?

相同点:都可以接收属性并返回React元素

不同点:编程思想不同,类组件为面向对象方式编程,函数组件为函数式编程的思想
内存占用:类组件需要创建并保存实例,占用一定的内存,而函数组件不需要创建实例,可以节省内存。
值捕获:函数组件具有值捕获特性。也就是使用一个计时器去获取最初的值得时候,函数组件中进行读取值不会变成状态更新之后的。
可测试性:函数式组件更方便编写单元测试。
状态:类组件有自己的实例,可以自己定义状态,修改状态更新组件。函数式组件以前没有状态,现在可以使用UseState使用状态。
生命周期:类组件有自己完整的生命周期,函数可以使用UseEffect实现生命周期的功能。
逻辑复用:类组件可以使用继承实现逻辑的复用。函数组件使用HOOKs实现。
跳过更新:类组件可以使用shouldComponentUpdate()和PureComponent组件来跳过更新,函数式组件可以使用React.memo来跳过更新。

16.react的渲染流程。

react16+的渲染流程:
scheduler选择高优先级的任务进行reconciler
reconciler计算变更的内容。
react-dom把变更的内容渲染到页面上。
设计理念:
跨平台渲染=>虚拟dom
快速响应=异步可中断+增量更新

17.diff算法?

diff算法的作用

计算出Virtual DOM中真正变化的部分,并只针对该部分进行原生DOM操作,而非重新渲染整个页面。

React的diff算法

什么是调和?

将Virtual DOM树转换成actual DOM树的最少操作的过程 称为 调和 。

什么是React diff算法?

diff算法是调和的具体实现。

diff策略
策略一(tree diff):

  • Web UI中DOM节点跨层级的移动操作特别少,可以忽略不计
  • 同级比较,既然DOM 节点跨层级的移动操作少到可以忽略不计,那么React通过updateDepth 对 Virtual DOM
    树进行层级控制,也就是同一层,在对比的过程中,如果发现节点不在了,会完全删除不会对其他地方进行比较,这样只需要对树遍历一次就OK了
    策略二(component diff):
  • 拥有相同类的两个组件 生成相似的树形结构,
  • 拥有不同类的两个组件 生成不同的树形结构。
    策略三(element diff):
    对于同一层级的一组子节点,通过唯一id区分。

tree diff

  • React通过updateDepth对Virtual DOM树进行层级控制。
  • 对树分层比较,两棵树 只对同一层次节点 进行比较。如果该节点不存在时,则该节点及其子节点会被完全删除,不会再进一步比较。
  • 只需遍历一次,就能完成整棵DOM树的比较
    component diff
  • 同一类型的两个组件,按原策略(层级比较)继续比较Virtual DOM树即可。
  • 同一类型的两个组件,组件A变化为组件B时,可能Virtual DOM没有任何变化,如果知道这点(变换的过程中,Virtual
    DOM没有改变),可节省大量计算时间,所以 用户 可以通过 shouldComponentUpdate() 来判断是否需要 判断计算。
  • 不同类型的组件,将一个(将被改变的)组件判断为dirty component(脏组件),从而替换 整个组件的所有节点。

element diff
插入:组件 C 不在集合(A,B)中,需要插入
删除:
组件 D 在集合(A,B,D)中,但 D的节点已经更改,**不能复用和更新,**所以需要删除 旧的 D ,再创建新的。
组件 D 之前在 集合(A,B,D)中,但集合变成新的集合(A,B)了,D 就需要被删除。
移动:组件D已经在集合(A,B,C,D)里了,且集合更新时,D没有发生更新,只是位置改变,如新集合(A,D,B,C),D在第二个,无须像传统diff,让旧集合的第二个B和新集合的第二个D 比较,并且删除第二个位置的B,再在第二个位置插入D,而是 (对同一层级的同组子节点) 添加唯一key进行区分,移动即可。

diff的不足与待优化的地方

尽量减少类似将最后一个节点移动到列表首部的操作,当节点数量过大或更新操作过于频繁时,会影响React的渲染性能

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/9864.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【从零开始学Skynet】工具篇(二):虚拟机文件的复制粘贴

大家在Linux系统下开发的时候肯定会遇到虚拟机与主机间无法复制粘贴的问题&#xff0c;现在我们就来解决这样的问题&#xff0c;方便我们的开发。 1、打开设置 我们可以系统界面的菜单栏点击“控制”&#xff0c;然后打开“设置”&#xff1b; 也可以在VirtualBox界面打开“设…

项目管理中,这些思维误区一定要避开

项目需要在限定的时间要求完成的事情&#xff0c;可控的关键把握是&#xff1a;人、时、事。 但是&#xff0c;项目实施时间一般较长&#xff0c;总有很多项目实施结果不尽人意。那么&#xff0c;IT项目管理过程中&#xff0c;容易出现哪些思维误区呢&#xff1f; 1、忘记项…

TCP三次握手四次挥手及time_wait状态解析

TCP的建立——三次握手 1.服务器必须准备好接受外来的连接。通常通过调用socket&#xff0c;bind&#xff0c;listen这三个函数来完成&#xff0c;我们称之为被动打开(passive open)。 2. 客户端通过调用connect函数发起主动的打开(active open)。这导致客户TCP发送一个SYN(同步…

Nginx基础教程

Nginx 目标 Nginx简介【了解】 Nginx安装配置【掌握】 一、Nginx简介 Nginx称为:负载均衡器或 静态资源服务器:html,css,js,img ​ Nginx(发音为“engine X”)是俄罗斯人编写的十分轻量级的HTTP服务器,是一个高性能的HTTP和反向代理服务器&#xff0c;同时也是一个IMAP/P…

初探MyBatis实现简单查询

文章目录一、创建数据库与表1、创建数据库2、创建用户表3、添加表记录二、基于配置文件方式使用MyBatis1、创建Maven项目2、添加相关依赖3、创建用户实体类4、创建用户映射器配置文件5、创建MyBatis配置文件6、创建日志属性文件7、测试用户操作1)创建用户操作测试类2)测试按编号…

除了Jira、禅道还有哪些更好的敏捷开发过程管理平台?

无论是从国内的敏捷调研开发调研报告还是从国外的敏捷状态调查&#xff0c;工具支持一直是决定敏捷成功的关键因素之一&#xff0c;它们可以帮助团队提高软件开发的效率、质量、协作和满意度。选择合适的敏捷开发管理工具&#xff0c;并正确地使用它们&#xff0c;是每个敏捷团…

数字孪生(1)

目前接触的客户群体是做大屏展示&#xff0c;闲鱼上5元包邮的那种科技感前端&#xff08;不好意思我买了&#xff09;各路模型大整合 实景GISiOT&#xff0c;如果再来点动画就好&#xff0c;然满屏动起来&#xff0c;火灾烧起来&#xff0c;水面荡漾起来&#xff0c;工程车开起…

C/C++每日一练(20230414)

目录 1. 寻找峰值 &#x1f31f;&#x1f31f; 2. 相同的树 &#x1f31f; 3. 整数反转 ※ &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1. 寻找峰值 峰值元素是指其值严格大于左右…

如何借助ChatGPT,自动批量产出短视频爆款文案

如何借助chatgpt批量出爆款文案。 这里我们首先得认识并了解到爆款文案的逻辑。 共通性是打动人&#xff0c;去原创的话&#xff0c;文案能否火&#xff0c;纯靠天吃饭。 所以我们让chatgpt去自己写原创短视频文案&#xff0c;那么chatgpt大概率自由发挥&#xff0c;我们也不…

国产化ChatGPT来袭,景联文科技提供专业数据采集标注服务,人手一个专属ChatGPT或成为可能

ChatGPT作为一个颠覆性的创新&#xff0c;现已成为火爆全球的智能应用。 自ChatGPT爆火以来&#xff0c;国内科技圈开始频频发力&#xff0c;多家科技和互联网公司纷纷表示将开发出中国本土化的ChatGPT。 以百度为例&#xff0c;3月16日&#xff0c;百度推出新一代知识增强大语…

【Linux】页表的深入分析

上一篇文章介绍了线程的基本概念 而本篇文章我们来深入理解一下, CPU再调度我们以往理解的进程和如今的线程都会涉及到的一个内容: 页表 文章目录深入理解页表 *页表的实际组成*什么是page&#xff1f;深入理解页表 * 在介绍进程时, 博主没有深入介绍过页表. 只是简单说了 页…

展心展力 metaapp:基于 DeepRec 的稀疏模型训练实践

作者 metaapp-推荐广告研发部&#xff1a;臧若舟&#xff0c;朱越&#xff0c;司灵通 1 背景 推荐场景大模型在国内的使用很早&#xff0c;早在 10 年前甚至更早&#xff0c;百度已经用上了自研的大规模分布式的 parameter server 系统结合上游自研的 worker 来实现 TB 级别…

“三箭齐发”,诸葛智能三大产品全新升级,助力企业迈向数字化经营 | 爱分析调研

调研&#xff1a;文鸿伟 撰写&#xff1a;文鸿伟 诸葛智能&#xff0c;是容联云旗下敏捷开放的场景化数据智能服务商&#xff0c;累积服务全国1000企业&#xff0c;覆盖泛互联网、泛电商、金融、汽车、产业科技、企服等数十个垂直领域。 自2015年成立至今&#xff0c;诸葛智…

数据库管理-第六十五期 Oracle 23c新特性(20230411)

数据库管理 2023-04-11第六十五期 Oracle 23c新特性1 免费版23c目录结构2 新特性总结第六十五期 Oracle 23c新特性 上一期装了免费版23c&#xff0c;这一期根据安装的数据库&#xff0c;对Oracle 23c的部分新特性进行实验展示。 1 免费版23c目录结构 通过RPM包安装的免费版2…

背包问题-动态规划

背包问题 容量有限的背包&#xff0c;给很多商品&#xff0c;商品有相应的体积与价值 01背包问题 一个背包 每个物品只有一个 最终状态方程 dp[i][j]max(dp[i-1][j],dp[i-1][j-w[i]]v[i]) 推导过程 由上一层推导过来 选择拿不拿i 最终代码 #include<iostream> #…

前段时间面了10多个人,发现这些测试人都有个通病......

前段时间面了15个人&#xff0c;怎么说呢&#xff0c;基本上没有符合要求的&#xff0c;其实一开始瞄准的就是中级的水准&#xff0c;也没指望来大牛&#xff0c;提供的薪资在10-20k&#xff0c;面试的人很多&#xff0c;但平均水平很让人失望。 看简历很多都是3年工作经验&am…

GitHub标星15w,如何用Python实现所有算法?

学会了 Python 基础知识&#xff0c;想进阶一下&#xff0c;那就来点算法吧&#xff01;毕竟编程语言只是工具&#xff0c;结构算法才是灵魂。 新手如何入门 Python 算法&#xff1f; 几位印度小哥在 GitHub 上建了一个各种 Python 算法的新手入门大全。从原理到代码&#xf…

数据 数据元素 数据项 数据对象

文章目录数据、数据元素、数据项和数据对象数据数据元素数据对象数据元素和数据对象数据结构数据结构包括以下三个方面的内容逻辑结构物理结构&#xff08;存储结构&#xff09;逻辑结构与存储结构的关系逻辑结构的种类集合结构线性结构树型结构图状结构或网状结构四种基本的存…

webgl-根据鼠标点击而移动

html <!DOCTYPE html> <head> <style> *{ margin: 0px; padding: 0px; } </style> </head> <body> <canvas id webgl> 您的浏览器不支持HTML5,请更换浏览器 </canvas> <script src"./main.js"></script&g…

【NAS群晖drive异地访问】远程连接drive挂载电脑硬盘「内网穿透」

文章目录前言1.群晖Synology Drive套件的安装1.1 安装Synology Drive套件1.2 设置Synology Drive套件1.3 局域网内电脑测试和使用2.使用cpolar远程访问内网Synology Drive2.1 Cpolar云端设置2.2 Cpolar本地设置2.3 测试和使用3. 结语转发自CSDN远程穿透的文章&#xff1a;【群晖…