React常见面试题

简介: React常见面试题

1.说说你对react的理解?有哪些特性?

React是一个前端js框架

React高效灵活

声明式设计,使用简单

组件式开发,提高代码的复用率

单向的数据绑定比双向的数据绑定更加安全


2.说说Real DOM和Virtual DOM的区别?优缺点?

1)虚拟dom不会进行重绘和回流,而真实dom会频繁重排与重绘

2)虚拟dom的总损耗是”虚拟dom的增删改+真实dom的差异增删改+重排“;真实dom的消耗是”真实dom全部增删改+重排“

真实dom

优点:直接操作HTML,易用

缺点:

1)解析速度慢,效率低,内存占用量高

2)性能差:频繁操作真实DOM,导致重绘、回流

虚拟dom

优点:

1)减少真实dom的频繁更新,减少重绘回流、占用内存少

2)跨平台:一套react代码可以多端运行

缺点:页面首次渲染时,由于多一层虚拟dom的计算,速度比正常慢些


3.说说React生命周期有哪些不同的阶段?每个阶段对应的方法?

挂载卸载过程

constructor,完成了React数据的初始化;

componentWillMount,组件初始化数据后,未渲染DOM前;

componentDidMount,组件第一次渲染完成,dom节点已经生成;

componentWillUnmount,组件的卸载和数据的销毁。

更新过程

componentWillReceiveProps (nextProps),父组件改变后的props需要重新渲染组件时;

shouldComponentUpdate(nextProps,nextState),主要用于性能优化(部分更新),

因为react父组件的重新渲染会导致其所有子组件的重新渲染,这个时候不需要所有子组件都跟着重新渲染,

然后return false就可以阻止组件的更新;

componentWillUpdate (nextProps,nextState),shouldComponentUpdate返回true后,

组件进入重新渲染的流程;

componentDidUpdate(prevProps,prevState),组件更新完毕后触发;

render(),渲染时触发


4.说说React中setState执行机制?

简单版本

React 利用状态队列机制实现了 setState 的“异步”更新,避免频繁的重复更新 state。

首先将新的 state 合并到状态更新队列中,然后根据更新队列和 shouldComponentUpdate 的状态来判断是否需要更新组件

复杂版本


enqueueSetState 将 state 放入队列中,并调用 enqueueUpdate 处理要更新的 Component

如果组件当前正处于 update 事务中,则先将 Component 存入 dirtyComponent 中。否则调用batchedUpdates 处理。

batchedUpdates 发起一次 transaction.perform() 事务

开始执行事务初始化,运行,结束三个阶段

初始化:事务初始化阶段没有注册方法,无方法要执行

运行:执行 setSate 时传入的 callback 方法

结束:更新 isBatchingUpdates 为 false,并执行 FLUSH_BATCHED_UPDATES 这个 wrapper 中的close方法,FLUSH_BATCHED_UPDATES在close阶段,会循环遍历所有的 dirtyComponents,调用updateComponent 刷新组件,并执行它的 pendingCallbacks, 也就是 setState 中设置的 callback。

flush_batched_updates

5.说说react的事件机制?

<div onClick={this.handleClick.bind(this)}>点我</div>

React并不是将click事件绑定到了div的真实DOM上,而是在document处监听了所有的事件,当事件发生并且冒泡到document处的时候,React将事件内容封装并交由真正的处理函数运行。这样的方式不仅减少了内存的消耗,还能在组件挂在销毁时统一订阅和移除事件。

JSX 上写的事件并没有绑定在对应的真实 DOM 上,而是通过事件代理的方式,将所有的事件都统一绑定在了 document 上。这样的方式不仅减少了内存消耗,还能在组件挂载销毁时统一订阅和移除事件。

另外冒泡到 document 上的事件也不是原生浏览器事件,而是 React 自己实现的合成事件(SyntheticEvent)。因此我们如果不想要事件冒泡的话,调用 event.stopPropagation 是无效的,而应该调用 event.preventDefault。

实现合成事件的目的如下:

合成事件首先抹平了浏览器之间的兼容问题,另外这是一个跨浏览器原生事件包装器,赋予了跨浏览器开发的能力;

对于原生浏览器事件来说,浏览器会给监听器创建一个事件对象。

如果有很多的事件监听,那么就需要分配很多的事件对象,造成高额的内存分配问题。

但是对于合成事件来说,有一个事件池专门来管理它们的创建和销毁,

当事件需要被使用时,就会从池子中复用对象,

事件回调结束后,就会销毁事件对象上的属性,从而便于下次复用事件对象


6.React组件之间如何通信?

1)父组件向子组件传递:

父组件在调用子组件的时候,在子组件标签内传递参数,子组件通过props属性就能接收父组件传递过来的参数

2)子组件向父组件传递:

父组件向子组件传一个函数,然后通过这个函数的回调,拿到子组件传过来的值

3)兄弟组件之间的通信:

父组件作为中间层来实现数据的互通,通过使用父组件传递

4)父组件向后代组件传递:

使用context提供了组件之间通讯的一种方式,可以共享数据,其他数据都能读取对应的数据

通过使用React.createContext创建一个context;

context创建成功后,其下存在Provider组件用于创建数据源,Consumer组件用于接收数据

Provider组件通过value属性用于给后代组件传递数据

如果想要获取Provider传递的数据,可以通过Consumer组件或者或者使用contextType属性接收

5)非关系组件传递:

将数据进行一个全局资源管理,从而实现通信


7.说说你对受控组件和非受控组件的理解?应用场景?

1)受控组件:指的是这个值受到setState()的影响,当页面刷新时,它会根据是值是否变化进行刷新

2)非受控组件:指的是不受setState()的影响,像input框中的值,只取决于本身DOM节点的值,从新属性是值不发生变化


8.说说你对fiber架构的理解?

Fiber 可以理解为一个执行单元,每次执行完一个执行单元,react 就会检查现在还剩多少时间,如果没有时间则将控制权让出去。

首先 React 向浏览器请求调度,浏览器在一帧中如果还有空闲时间,会去判断是否存在待执行任务,不存在就直接将控制权交给浏览器,如果存在就会执行对应的任务,执行完成后会判断是否还有时间,有时间且有待执行任务则会继续执行下一个任务,否则就会将控制权交给浏览器。


9.说说react diff的原理是什么?

1)Diff算法是虚拟DOM的一个必然结果,它是通过新旧DOM的对比,

将在不更新页面的情况下,将需要内容局部更新

2)Diff算法遵循深度优先,同层比较的原则

3)可以使用key值,可以更加准确的找到DOM节点

react中diff算法主要遵循三个层级的策略:

tree层级

conponent 层级

element 层级

tree层不会做任何修改,如果有不一样,直接删除创建

component层从父级往子集查找,如果发现不一致,直接删除创建

element层有key值做比较,如果发现key值可以复用的话,就会将位置进行移动,如果没有,则执行删除创建


10.说说你对redux中间件的理解?常用的中间件有哪些?

1)中间件(Middleware)在计算机中,是介于应用系统和系统软件之间的一类软件,它使用系统软件所提供的基础服务(功能),衔接网络上应用系统的各个部分或不同的应用,能够达到资源共享、功能共享的目的

2)redux-thunk:用于异步操作

3)redux-logger:用于日志记录

4)redux中间件就是辅助redux不能完成的功能

5)applayMiddleWare()

6)将它包裹在要使用的插件外部


11.如何使用css实现一个三角形?

.box {
    /* 内部大小 */
    width: 0px;
    height: 0px;
    /* 边框大小 只设置两条边*/
    border-top: #4285f4 solid;
    border-right: transparent solid;
    border-width: 85px; 
    /* 其他设置 */
    margin: 50px;
}

12.什么是强缓存和协商缓存?

浏览器首次请求资源后,需要再次请求时,浏览器会首先获取该资源缓存的header信息,

然后根据Cache-Control和expires来判断该资源在本地缓存否过期

没过期:直接从本地缓存中获取资源信息,浏览器就不再向服务器重新请求资源,

过期:需重新发送请求,重新缓存资源,更新缓存时间

强缓存是利用http请求头中的Expires和Cache-Control两个字段来进行控制,用来表示资源的缓存时间


协商缓存是服务器用来确定缓存资源是否可用过期

因为服务器需要向浏览器确认缓存资源是否可用,二者要进行通信,

而通信的过程就是发送请求,所以在header中就需要有专门的标识来让服务器确认请求资源是否可以缓存访问,

所以就有了两组header字段

Etag和If-None-Match

Last-Modified和If-Modified-Since


13.说说React jsx转换成真实DOM的过程?

使用React.createElement或JSX编写React组件,实际上所有的 JSX 代码最后都会转换成React.createElement(…) ,Babel帮助我们完成了这个转换的过程。

createElement函数对key和ref等特殊的props进行处理,并获取defaultProps对默认props进行赋值,并且对传入的孩子节点进行处理,最终构造成一个虚拟DOM对象

ReactDOM.render将生成好的虚拟DOM渲染到指定容器上,其中采用了批处理、事务等机制并且对特定浏览器进行了性能优化,最终转换为真实DOM


14.说说你对@reduxjs/toolkit的理解?

reduxjs/toolkit:

Redux 官方强烈推荐,开箱即用的一个高效的 Redux 开发工具集。它旨在成为标准的 Redux 逻辑开发模式,使用 Redux Toolkit 都可以优化你的代码,使其更可维护

react-redux:

react官方推出的redux绑定库,react-redux将所有组件分为两大类:UI组件和容器组件,其中所有容器组件包裹着UI组件,构成父子关系。容器组件负责和redux交互,里面使用redux API函数,UI组件负责页面渲染,不使用任何redux API。容器组件会给UI组件传递redux中保存对的状态和操作状态的方法 #


15.React render方法的原理,在什么时候会触发?

原理:

在类组件中render函数指的就是render方法;而在函数组件中,指的就是整个函数组件

render函数中的jsx语句会被编译成我们熟悉的js代码,在render过程中,react将新调用的render函

数返回的树与旧版本的树进行比较,这一步是决定如何更新 DOM 的必要步骤,然后进行 diff 比

较,更新dom树

触发时机:

类组件调用 setState 修改状态

函数组件通过useState hook修改状态

一旦执行了setState就会执行render方法,useState 会判断当前值有无发生改变确定是否执行

render方法,一旦父组件发生渲染,子组件也会渲染


16.React性能优化的手段有哪些?

1)避免使用内联函数

2)使用react fragement 避免额外标记

3)immutable,减少渲染的次数,为了避免重复渲染,会在shouldComponentUpdate()中做对

比,当返回true,执行render方法。immutable通过is方法完成对比

4)懒加载组件

5)事件绑定方式(在constructor中使用bind绑定性能更高)

6)服务端渲染

7)组件拆分,合理使用hooks


17.如何通过原生js实现一个节流函数和防抖函数?

防抖:

const debounce = (func, wait = 50) => {
  let timer = 0
  return function(...args) {
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
      func.apply(this, args)
    }, wait)
  }
}

节流:

export const throttle = function (fn, wait = 500) {
  let flg = true
  return function () {
    if (!flg) return;
    flg = false
    setTimeout(() => {
      fn.apply(this, arguments)
      flg = true
    }, wait);
  }
}

18.说说webpack中常见的loader?解决了什么问题?

style-loader: 将css添加到DOM的内联样式标签style里

css-loader :允许将css文件通过require的方式引入,并返回css代码

less-loader: 处理less

sass-loader: 处理sass

postcss-loader: 用postcss来处理CSS

autoprefixer-loader: 处理CSS3属性前缀,已被弃用,建议直接使用postcss

file-loader: 分发文件到output目录并返回相对路径

url-loader: 和file-loader类似,但是当文件小于设定的limit时可以返回一个Data Url

html-minify-loader: 压缩HTML

babel-loader :用babel来转换ES6文件到ES


19.说说如何借助webpack来优化前端性能?

JS代码压缩

CSS代码压缩

Html文件代码压缩

文件大小压缩

图片压缩

Tree Shaking

代码分离

内联 chunk


20.说说javascript内存泄漏的几种情况?

意外使用全局变量(比如函数内部使用全局变量)

定时器不清除,一直占用内存,得不到释放

或者在定时器内调用外部函数,得不到释放

闭包,内部函数引用外部函数变量,得不到释放

不清理dom元素的引用

监听事件的解除,监听的时候addEventListener,在不监听的时候要使用


21.对React中虚拟dom的理解?

1)虚拟DOM本质上是一个Object类型的对象

2)虚拟DOM比较轻,真实DOM比较重,虚拟DOM是React内部使用,虚拟DOM不需要真实DOM上那么多的属性

3)虚拟DOM最终回被React渲染到页面上


22.对react hook的理解?

1)hook是React新增的一个特性

2)Hook主要解决了函数组件没有生命周期,没有状态,一些自身逻辑的问题,还有提高的代码的复用率

3)Hook的一些方法:useState(),useRef(),useCallBack(),useReduer(),useEffect()


23.Connect组件的原理是什么?

connect 的第一个参数是 mapStateToProps

这个函数允许我们将 store 中的数据作为 props 绑定到组件上

connect 的第二个参数是 mapDispatchToProps

由于更改数据必须要触发action, 因此在这里的主要功能是将 action 作为props 绑定到 组件上

Provider就是react-redux中的一个组件, Provider 做的事情也简单, 它就是一个容器组件, 会把嵌套的内容原封不动作为自己的子组件渲染出来. 它还会把外界传给它的 props.store 放到 context


24.对koa中洋葱模型的理解?

Koa是一个精简的node框架,被认为是第二代Node框架,其最大的特点就是独特的中间件流程控制,是一个典型的洋葱模型,它的核心工作包括下面两个方面:

将node原生的req和res封装成为一个context对象。

基于async/await的中间件洋葱模型机制

Koa的洋葱模型是以next()函数为分割点,先由外到内执行Request的逻辑,然后再由内到外执行Response的逻辑,这里的request的逻辑,我们可以理解为是next之前的内容,response的逻辑是next函数之后的内容,也可以说每一个中间件都有两次处理时机。洋葱模型的核心原理主要是借助compose方法。


25. 对WebSocket的理解?

WebSocket,是一种网络传输协议,位于OSI模型的应用层。可在单个TCP连接上进行全双工通信,能更好的节省服务器资源和带宽并达到实时通迅

客户端和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输

较少的控制开销:数据包头部协议较小,不同于http每次请求需要携带完整的头部

更强的实时性:相对于HTTP请求需要等待客户端发起请求服务端才能响应,延迟明显更少

保持创连接状态:创建通信后,可省略状态信息,不同于HTTP每次请求需要携带身份验证

更好的二进制支持:定义了二进制帧,更好处理二进制内容

支持扩展:用户可以扩展websocket协议、实现部分自定义的子协议

更好的压缩效果:Websocket在适当的扩展支持下,可以沿用之前内容的上下文,在传递类似的数据时,可以显著地提高压缩率


26.react中refs是什么?

refs是提供一种访问在render方法中创建DOM节点或者React元素的方法,在典型的数据流中,props是父子组件交互的唯一方式,想要修改子组件,需要使用新的props重新渲染它,某些情况下,在典型的数据流外,强制修改子代,这个时候可以使用refs

我们可以在组件添加一个ref属性来使用,该属性是一个回调函数,接收作为其第一个参数的底层DOM元素或组件挂载实例

input元素有一个ref属性,他的值是一个函数,该函数接收输入的实际DOM元素,然后将其放在实例上,这样就可以在 handleSubmit 函数内部访问它

经常被误解的只有在类组件中才能使用 refs,但是refs也可以通过利用 JS 中的闭包与函数组件一起使用


27.state和props区别是什么?

相同点:都是普通的js对象,他们包含着影响渲染输出的信息

不同点:state是组件自己管理数据,控制自己的状态,可变

props是外部传入的数据参数,不可变

没有state的叫做无状态组件,有state的叫有状态组件

多用props,少用state


28.React 组件生命周期有哪些不同阶段?

Initialization:在这个阶段,组件准备设置初始化状态和默认属性。

Mounting:react 组件已经准备好挂载到浏览器 DOM 中。这个阶段包括componentWillMount和componentDidMount生命周期方法。

Updating:在这个阶段,组件以两种方式更新,发送新的 props 和 state 状态。此阶段包括shouldComponentUpdate、componentWillUpdate和componentDidUpdate生命周期方法。

Unmounting:在这个阶段,组件已经不再被需要了,它从浏览器 DOM 中卸载下来。这个阶段包含 componentWillUnmount 生命周期方法。

除以上四个常用生命周期外,还有一个错误处理的阶段:

Error Handling:在这个阶段,不论在渲染的过程中,还是在生命周期方法中或是在任何子组件的构造函数中发生错误,该组件都会被调用。这个阶段包含了 componentDidCatch 生命周期方法。


29.React 中的StrictMode(严格模式)是什么?

React 的StrictMode是一种辅助组件,可以帮助咱们编写更好的 react 组件,可以使用包装一组组件,并且可以帮咱们以下检查:

验证内部组件是否遵循某些推荐做法,如果没有,会在控制台给出警告。

验证是否使用的已经废弃的方法,如果有,会在控制台给出警告。

通过识别潜在的风险预防一些副作用。


30.如何避免组件的重新渲染?

React 中最常见的问题之一是组件不必要地重新渲染。React 提供了两个方法,在这些情况下非常有用:

React.memo():这可以防止不必要地重新渲染函数组件

PureComponent:这可以防止不必要地重新渲染类组件

这两种方法都依赖于对传递给组件的props的浅比较,如果 props 没有改变,那么组件将不会重新渲染。虽然这两种工具都非常有用,但是浅比较会带来额外的性能损失,因此如果使用不当,这两种方法都会对性能产生负面影响。

通过使用 React Profiler,可以在使用这些方法前后对性能进行测量,从而确保通过进行给定的更改来实际改进性能。


31.当调用setState时,React render 是如何工作的?

虚拟 DOM 渲染:当render方法被调用时,它返回一个新的组件的虚拟 DOM 结构。当调用setState()时,render会被再次调用,因为默认情况下shouldComponentUpdate总是返回true,所以默认情况下 React 是没有优化的。

原生 DOM 渲染:React 只会在虚拟DOM中修改真实DOM节点,而且修改的次数非常少——这是很棒的React特性,它优化了真实DOM的变化,使React变得更快。


32.React的一些主要优点?

1)它提高了应用的性能

2)可以方便地在客户端和服务器端使用

3)由于 JSX,代码的可读性很好

4)React 很容易与 Meteor,Angular 等其他框架集成

5)使用React,编写UI测试用例变得非常容易


33.React有哪些限制?

1)React 只是一个库,而不是一个完整的框架

2)它的库非常庞大,需要时间来理解

3)新手程序员可能很难理解

4)编码变得复杂,因为它使用内联模板和 JSX


34.为什么浏览器无法读取JSX?

浏览器只能处理 JavaScript 对象,而不能读取常规 JavaScript 对象中的 JSX。所以为了使浏览器能够读取 JSX,首先,需要用像 Babel 这样的 JSX 转换器将 JSX 文件转换为 JavaScript 对象,然后再将其传给浏览器


35. React中的合成事件是什么?

合成事件是围绕浏览器原生事件充当跨浏览器包装器的对象。它们将不同浏览器的行为合并为一个 API。这样做是为了确保事件在不同浏览器中显示一致的属性。


36.React 中 key 的重要性是什么?

key 用于识别唯一的 Virtual DOM 元素及其驱动 UI 的相应数据。它们通过回收 DOM 中当前所有的元素来帮助 React 优化渲染。这些 key 必须是唯一的数字或字符串,React 只是重新排序元素而不是重新渲染它们。这可以提高应用程序的性能


37.Redux遵循的三个原则是什么?

单一事实来源:整个应用的状态存储在单个 store 中的对象/状态树里。单一状态树可以更容易地跟踪随时间的变化,并调试或检查应用程序。

状态是只读的:改变状态的唯一方法是去触发一个动作。动作是描述变化的普通 JS 对象。就像 state 是数据的最小表示一样,该操作是对数据更改的最小表示。

使用纯函数进行更改:为了指定状态树如何通过操作进行转换,你需要纯函数。纯函数是那些返回值仅取决于其参数值的函数。


38.对“单一事实来源”有什么理解?

Redux 使用 “Store” 将程序的整个状态存储在同一个地方。因此所有组件的状态都存储在 Store 中,并且它们从 Store 本身接收更新。单一状态树可以更容易地跟踪随时间的变化,并调试或检查程序


39.列出 Redux 的组件

Action – 这是一个用来描述发生了什么事情的对象。

Reducer – 这是一个确定状态将如何变化的地方。

Store – 整个程序的状态/对象树保存在Store中。

View – 只显示 Store 提供的数据。


40.Redux 有哪些优点?

结果的可预测性 - 由于总是存在一个真实来源,即 store ,因此不存在如何将当前状态与动作和应用的其他部分同步的问题。

可维护性 - 代码变得更容易维护,具有可预测的结果和严格的结构。

服务器端渲染 - 你只需将服务器上创建的 store 传到客户端即可。这对初始渲染非常有用,并且可以优化应用性能,从而提供更好的用户体验。

开发人员工具 - 从操作到状态更改,开发人员可以实时跟踪应用中发生的所有事情。

社区和生态系统 - Redux 背后有一个巨大的社区,这使得它更加迷人。一个由才华横溢的人组成的大型社区为库的改进做出了贡献,并开发了各种应用。

易于测试 - Redux 的代码主要是小巧、纯粹和独立的功能。这使代码可测试且独立。

组织 - Redux 准确地说明了代码的组织方式,这使得代码在团队使用时更加一致和简单


41.React中常用的hooks

useState:定义state的数据,参数是初始化的数据,返回值两个值1. 初始化值,2. 修改的方法

useEffect:副作用函数,顾名思义,副作用即只有使用过后才会产生副作用

useMemo:用来计算数据,返回一个结果,监听数据的变化,第二个参数就是监听的数据,具有缓存性

useRef:相当于createRef的使用,创建组件的属性信息

useContext:相当在函数组件中获取context状态数的内容信息

useReducer:useReducer是用来弥补useState的补不足, 可以把数据进行集中式的管理,单独处理数据的逻辑信息


42.useMemo是怎么做性能优化的?

当父组件向子组件组件通信的时候,父组件中数据发生改变,更新父组件导致子组件的更新渲染,但是如果修改的数据跟子组件无关的话,更新子组件会导致子组件不必要的DOM渲染,是比较消耗性能的,这个时候我们可以使用useMemo或者memo做组件的缓存,减少子组件不必要的DOM渲染


相关文章
|
2月前
|
JSON 缓存 前端开发
【React】React原理面试题集锦
本文集合一些React的原理面试题,方便读者以后面试查漏补缺。作者给出自认为可以让面试官满意的简易答案,如果想要了解更深刻,可以点击链接查看对应的详细博文。在此对链接中的博文作者非常感谢🙏。
37 0
|
4月前
|
前端开发 JavaScript
【第41期】一文入围React面试
【第41期】一文入围React面试
36 0
|
4月前
|
缓存 前端开发 JavaScript
【面试题】金九银十,你准备好面试了吗? (30w字前端面试题总结)( React)
【面试题】金九银十,你准备好面试了吗? (30w字前端面试题总结)( React)
|
2月前
|
存储 缓存 前端开发
【React】Hooks面试题集锦
本文集合一些React的Hooks面试题,方便读者以后面试查漏补缺。作者给出自认为可以让面试官满意的简易答案,如果想要了解更深刻,可以点击链接查看对应的详细博文。在此对链接中的博文作者非常感谢🙏。
59 1
|
4月前
|
缓存 前端开发 JavaScript
React 面试题2
React 面试题2
|
4月前
|
缓存 前端开发 JavaScript
React 面试题
React 面试题
115 0
|
5月前
|
JavaScript 前端开发
【金典面试题】Vue与React实现Tree
【金典面试题】Vue与React实现Tree
37 0
|
7月前
|
JavaScript 前端开发
React-组件state面试题
React-组件state面试题
34 0
|
9月前
|
XML JavaScript 前端开发
react面试题大全三
react面试题大全三
|
算法 JavaScript 前端开发
关于React面试题汇总
中间件提供第三方插件的模式,自定义拦截 action -> reducer 的过程。变为 action -> middlewares -> reducer 。这种机制可以让我们改变数据流,实现如异步 action ,action 过滤,日志输出,异常报告等功能。常见的中间件:
3522 0